diff --git a/.gitignore b/.gitignore index 2bac2d0aa..e0c63b4ec 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ sbom.json sbom-docker.json *_sbom.json *.out +*.DS_Store diff --git a/apps/console/src/hooks/graph/AuditGraph.ts b/apps/console/src/hooks/graph/AuditGraph.ts new file mode 100644 index 000000000..b0c7ec938 --- /dev/null +++ b/apps/console/src/hooks/graph/AuditGraph.ts @@ -0,0 +1,279 @@ +import { graphql } from "relay-runtime"; +import { useMutation } from "react-relay"; +import { useConfirm } from "@probo/ui"; +import { useTranslate } from "@probo/i18n"; +import { promisifyMutation, sprintf } from "@probo/helpers"; +import { useMutationWithToasts } from "../useMutationWithToasts"; + +export const auditsQuery = graphql` + query AuditGraphListQuery($organizationId: ID!) { + node(id: $organizationId) { + ... on Organization { + ...AuditsPageFragment + } + } + } +`; + +export const auditNodeQuery = graphql` + query AuditGraphNodeQuery($auditId: ID!) { + node(id: $auditId) { + ... on Audit { + id + validFrom + validUntil + report { + id + filename + mimeType + size + downloadUrl + createdAt + } + reportUrl + state + framework { + id + name + } + organization { + id + name + } + createdAt + updatedAt + } + } + } +`; + +export const createAuditMutation = graphql` + mutation AuditGraphCreateMutation( + $input: CreateAuditInput! + $connections: [ID!]! + ) { + createAudit(input: $input) { + auditEdge @prependEdge(connections: $connections) { + node { + id + validFrom + validUntil + report { + id + filename + } + state + framework { + id + name + } + createdAt + } + } + } + } +`; + +export const updateAuditMutation = graphql` + mutation AuditGraphUpdateMutation($input: UpdateAuditInput!) { + updateAudit(input: $input) { + audit { + id + validFrom + validUntil + report { + id + filename + } + state + framework { + id + name + } + updatedAt + } + } + } +`; + +export const deleteAuditMutation = graphql` + mutation AuditGraphDeleteMutation( + $input: DeleteAuditInput! + $connections: [ID!]! + ) { + deleteAudit(input: $input) { + deletedAuditId @deleteEdge(connections: $connections) + } + } +`; + +export const useDeleteAudit = ( + audit: { id: string; framework: { name: string } }, + connectionId: string +) => { + const { __ } = useTranslate(); + const [mutate] = useMutationWithToasts(deleteAuditMutation, { + successMessage: __("Audit deleted successfully"), + errorMessage: __("Failed to delete audit"), + }); + const confirm = useConfirm(); + + return () => { + confirm( + () => + mutate({ + variables: { + input: { + auditId: audit.id!, + }, + connections: [connectionId], + }, + }), + { + message: sprintf( + __( + "This will permanently delete the audit for %s. This action cannot be undone." + ), + audit.framework.name + ), + } + ); + }; +}; + +export const useCreateAudit = (connectionId: string) => { + const [mutate] = useMutation(createAuditMutation); + const { __ } = useTranslate(); + + return (input: { + organizationId: string; + frameworkId: string; + validFrom?: string; + validUntil?: string; + reportKey?: string; + state?: string; + }) => { + if (!input.organizationId) { + return alert(__("Failed to create audit: organization is required")); + } + if (!input.frameworkId) { + return alert(__("Failed to create audit: framework is required")); + } + + return promisifyMutation(mutate)({ + variables: { + input: { + organizationId: input.organizationId, + frameworkId: input.frameworkId, + validFrom: input.validFrom, + validUntil: input.validUntil, + reportKey: input.reportKey, + state: input.state || "NOT_STARTED", + }, + connections: [connectionId], + }, + }); + }; +}; + +export const useUpdateAudit = () => { + const [mutate] = useMutation(updateAuditMutation); + const { __ } = useTranslate(); + + return (input: { + id: string; + validFrom?: string; + validUntil?: string; + state?: string; + }) => { + if (!input.id) { + return alert(__("Failed to update audit: audit ID is required")); + } + + return promisifyMutation(mutate)({ + variables: { + input, + }, + }); + }; +}; + +export const uploadAuditReportMutation = graphql` + mutation AuditGraphUploadReportMutation($input: UploadAuditReportInput!) { + uploadAuditReport(input: $input) { + audit { + id + report { + id + filename + downloadUrl + createdAt + } + updatedAt + } + } + } +`; + +export const useUploadAuditReport = () => { + const { __ } = useTranslate(); + const [mutate, isLoading] = useMutationWithToasts(uploadAuditReportMutation, { + successMessage: __("Audit report uploaded successfully"), + errorMessage: __("Failed to upload audit report"), + }); + + const uploadAuditReport = (input: { auditId: string; file: File }) => { + if (!input.auditId) { + return alert(__("Failed to upload report: audit ID is required")); + } + + return mutate({ + variables: { + input: { + auditId: input.auditId, + file: null, + }, + }, + uploadables: { + "input.file": input.file, + }, + }); + }; + + return [uploadAuditReport, isLoading] as const; +}; + +export const deleteAuditReportMutation = graphql` + mutation AuditGraphDeleteReportMutation($input: DeleteAuditReportInput!) { + deleteAuditReport(input: $input) { + audit { + id + report { + id + filename + downloadUrl + createdAt + } + updatedAt + } + } + } +`; + +export const useDeleteAuditReport = () => { + const { __ } = useTranslate(); + const [mutate] = useMutationWithToasts(deleteAuditReportMutation, { + successMessage: __("Audit report deleted successfully"), + errorMessage: __("Failed to delete audit report"), + }); + + return (input: { auditId: string }) => { + return mutate({ + variables: { + input: { + auditId: input.auditId, + }, + }, + }); + }; +}; diff --git a/apps/console/src/hooks/graph/__generated__/AuditGraphCreateMutation.graphql.ts b/apps/console/src/hooks/graph/__generated__/AuditGraphCreateMutation.graphql.ts new file mode 100644 index 000000000..b3458bcfc --- /dev/null +++ b/apps/console/src/hooks/graph/__generated__/AuditGraphCreateMutation.graphql.ts @@ -0,0 +1,242 @@ +/** + * @generated SignedSource<> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +export type AuditState = "COMPLETED" | "IN_PROGRESS" | "NOT_STARTED" | "OUTDATED" | "REJECTED"; +export type CreateAuditInput = { + frameworkId: string; + organizationId: string; + state?: AuditState | null | undefined; + validFrom?: any | null | undefined; + validUntil?: any | null | undefined; +}; +export type AuditGraphCreateMutation$variables = { + connections: ReadonlyArray; + input: CreateAuditInput; +}; +export type AuditGraphCreateMutation$data = { + readonly createAudit: { + readonly auditEdge: { + readonly node: { + readonly createdAt: any; + readonly framework: { + readonly id: string; + readonly name: string; + }; + readonly id: string; + readonly report: { + readonly filename: string; + readonly id: string; + } | null | undefined; + readonly state: AuditState; + readonly validFrom: any | null | undefined; + readonly validUntil: any | null | undefined; + }; + }; + }; +}; +export type AuditGraphCreateMutation = { + response: AuditGraphCreateMutation$data; + variables: AuditGraphCreateMutation$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "connections" +}, +v1 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "input" +}, +v2 = [ + { + "kind": "Variable", + "name": "input", + "variableName": "input" + } +], +v3 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}, +v4 = { + "alias": null, + "args": null, + "concreteType": "AuditEdge", + "kind": "LinkedField", + "name": "auditEdge", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Audit", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v3/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "validFrom", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "validUntil", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "Report", + "kind": "LinkedField", + "name": "report", + "plural": false, + "selections": [ + (v3/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "filename", + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "state", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "Framework", + "kind": "LinkedField", + "name": "framework", + "plural": false, + "selections": [ + (v3/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "createdAt", + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null +}; +return { + "fragment": { + "argumentDefinitions": [ + (v0/*: any*/), + (v1/*: any*/) + ], + "kind": "Fragment", + "metadata": null, + "name": "AuditGraphCreateMutation", + "selections": [ + { + "alias": null, + "args": (v2/*: any*/), + "concreteType": "CreateAuditPayload", + "kind": "LinkedField", + "name": "createAudit", + "plural": false, + "selections": [ + (v4/*: any*/) + ], + "storageKey": null + } + ], + "type": "Mutation", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [ + (v1/*: any*/), + (v0/*: any*/) + ], + "kind": "Operation", + "name": "AuditGraphCreateMutation", + "selections": [ + { + "alias": null, + "args": (v2/*: any*/), + "concreteType": "CreateAuditPayload", + "kind": "LinkedField", + "name": "createAudit", + "plural": false, + "selections": [ + (v4/*: any*/), + { + "alias": null, + "args": null, + "filters": null, + "handle": "prependEdge", + "key": "", + "kind": "LinkedHandle", + "name": "auditEdge", + "handleArgs": [ + { + "kind": "Variable", + "name": "connections", + "variableName": "connections" + } + ] + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "5c941d42e42700b5e06a5a64c861054b", + "id": null, + "metadata": {}, + "name": "AuditGraphCreateMutation", + "operationKind": "mutation", + "text": "mutation AuditGraphCreateMutation(\n $input: CreateAuditInput!\n) {\n createAudit(input: $input) {\n auditEdge {\n node {\n id\n validFrom\n validUntil\n report {\n id\n filename\n }\n state\n framework {\n id\n name\n }\n createdAt\n }\n }\n }\n}\n" + } +}; +})(); + +(node as any).hash = "231fafa942acf107e2f0187bccc844da"; + +export default node; diff --git a/apps/console/src/hooks/graph/__generated__/AuditGraphDeleteMutation.graphql.ts b/apps/console/src/hooks/graph/__generated__/AuditGraphDeleteMutation.graphql.ts new file mode 100644 index 000000000..ffeae3355 --- /dev/null +++ b/apps/console/src/hooks/graph/__generated__/AuditGraphDeleteMutation.graphql.ts @@ -0,0 +1,132 @@ +/** + * @generated SignedSource<> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +export type DeleteAuditInput = { + auditId: string; +}; +export type AuditGraphDeleteMutation$variables = { + connections: ReadonlyArray; + input: DeleteAuditInput; +}; +export type AuditGraphDeleteMutation$data = { + readonly deleteAudit: { + readonly deletedAuditId: string; + }; +}; +export type AuditGraphDeleteMutation = { + response: AuditGraphDeleteMutation$data; + variables: AuditGraphDeleteMutation$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "connections" +}, +v1 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "input" +}, +v2 = [ + { + "kind": "Variable", + "name": "input", + "variableName": "input" + } +], +v3 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "deletedAuditId", + "storageKey": null +}; +return { + "fragment": { + "argumentDefinitions": [ + (v0/*: any*/), + (v1/*: any*/) + ], + "kind": "Fragment", + "metadata": null, + "name": "AuditGraphDeleteMutation", + "selections": [ + { + "alias": null, + "args": (v2/*: any*/), + "concreteType": "DeleteAuditPayload", + "kind": "LinkedField", + "name": "deleteAudit", + "plural": false, + "selections": [ + (v3/*: any*/) + ], + "storageKey": null + } + ], + "type": "Mutation", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [ + (v1/*: any*/), + (v0/*: any*/) + ], + "kind": "Operation", + "name": "AuditGraphDeleteMutation", + "selections": [ + { + "alias": null, + "args": (v2/*: any*/), + "concreteType": "DeleteAuditPayload", + "kind": "LinkedField", + "name": "deleteAudit", + "plural": false, + "selections": [ + (v3/*: any*/), + { + "alias": null, + "args": null, + "filters": null, + "handle": "deleteEdge", + "key": "", + "kind": "ScalarHandle", + "name": "deletedAuditId", + "handleArgs": [ + { + "kind": "Variable", + "name": "connections", + "variableName": "connections" + } + ] + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "48906b2f55360bea9a8fc7f0daea34be", + "id": null, + "metadata": {}, + "name": "AuditGraphDeleteMutation", + "operationKind": "mutation", + "text": "mutation AuditGraphDeleteMutation(\n $input: DeleteAuditInput!\n) {\n deleteAudit(input: $input) {\n deletedAuditId\n }\n}\n" + } +}; +})(); + +(node as any).hash = "e0f3771289e512982adc900199820821"; + +export default node; diff --git a/apps/console/src/hooks/graph/__generated__/AuditGraphDeleteReportMutation.graphql.ts b/apps/console/src/hooks/graph/__generated__/AuditGraphDeleteReportMutation.graphql.ts new file mode 100644 index 000000000..4d72952d4 --- /dev/null +++ b/apps/console/src/hooks/graph/__generated__/AuditGraphDeleteReportMutation.graphql.ts @@ -0,0 +1,153 @@ +/** + * @generated SignedSource<<14b4821bc7eec6b85029d0aae3a3a271>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +export type DeleteAuditReportInput = { + auditId: string; +}; +export type AuditGraphDeleteReportMutation$variables = { + input: DeleteAuditReportInput; +}; +export type AuditGraphDeleteReportMutation$data = { + readonly deleteAuditReport: { + readonly audit: { + readonly id: string; + readonly report: { + readonly createdAt: any; + readonly downloadUrl: string | null | undefined; + readonly filename: string; + readonly id: string; + } | null | undefined; + readonly updatedAt: any; + }; + }; +}; +export type AuditGraphDeleteReportMutation = { + response: AuditGraphDeleteReportMutation$data; + variables: AuditGraphDeleteReportMutation$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "input" + } +], +v1 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}, +v2 = [ + { + "alias": null, + "args": [ + { + "kind": "Variable", + "name": "input", + "variableName": "input" + } + ], + "concreteType": "DeleteAuditReportPayload", + "kind": "LinkedField", + "name": "deleteAuditReport", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Audit", + "kind": "LinkedField", + "name": "audit", + "plural": false, + "selections": [ + (v1/*: any*/), + { + "alias": null, + "args": null, + "concreteType": "Report", + "kind": "LinkedField", + "name": "report", + "plural": false, + "selections": [ + (v1/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "filename", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "downloadUrl", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "createdAt", + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "updatedAt", + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } +]; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "AuditGraphDeleteReportMutation", + "selections": (v2/*: any*/), + "type": "Mutation", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "AuditGraphDeleteReportMutation", + "selections": (v2/*: any*/) + }, + "params": { + "cacheID": "ebceb2fd2a2ffae09bc1578e37dde7e0", + "id": null, + "metadata": {}, + "name": "AuditGraphDeleteReportMutation", + "operationKind": "mutation", + "text": "mutation AuditGraphDeleteReportMutation(\n $input: DeleteAuditReportInput!\n) {\n deleteAuditReport(input: $input) {\n audit {\n id\n report {\n id\n filename\n downloadUrl\n createdAt\n }\n updatedAt\n }\n }\n}\n" + } +}; +})(); + +(node as any).hash = "4b5e9537b35458eb3daa313ead9ba655"; + +export default node; diff --git a/apps/console/src/hooks/graph/__generated__/AuditGraphListQuery.graphql.ts b/apps/console/src/hooks/graph/__generated__/AuditGraphListQuery.graphql.ts new file mode 100644 index 000000000..ccd3bbe84 --- /dev/null +++ b/apps/console/src/hooks/graph/__generated__/AuditGraphListQuery.graphql.ts @@ -0,0 +1,307 @@ +/** + * @generated SignedSource<<421ff1807db813d87849e15e60fc958e>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; +export type AuditGraphListQuery$variables = { + organizationId: string; +}; +export type AuditGraphListQuery$data = { + readonly node: { + readonly " $fragmentSpreads": FragmentRefs<"AuditsPageFragment">; + }; +}; +export type AuditGraphListQuery = { + response: AuditGraphListQuery$data; + variables: AuditGraphListQuery$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "organizationId" + } +], +v1 = [ + { + "kind": "Variable", + "name": "id", + "variableName": "organizationId" + } +], +v2 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null +}, +v3 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}, +v4 = [ + { + "kind": "Literal", + "name": "first", + "value": 10 + } +]; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "AuditGraphListQuery", + "selections": [ + { + "alias": null, + "args": (v1/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "kind": "InlineFragment", + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "AuditsPageFragment" + } + ], + "type": "Organization", + "abstractKey": null + } + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "AuditGraphListQuery", + "selections": [ + { + "alias": null, + "args": (v1/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v2/*: any*/), + (v3/*: any*/), + { + "kind": "InlineFragment", + "selections": [ + { + "alias": null, + "args": (v4/*: any*/), + "concreteType": "AuditConnection", + "kind": "LinkedField", + "name": "audits", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "AuditEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Audit", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v3/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "validFrom", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "validUntil", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "Report", + "kind": "LinkedField", + "name": "report", + "plural": false, + "selections": [ + (v3/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "filename", + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "state", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "Framework", + "kind": "LinkedField", + "name": "framework", + "plural": false, + "selections": [ + (v3/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "createdAt", + "storageKey": null + }, + (v2/*: 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 + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "hasPreviousPage", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "startCursor", + "storageKey": null + } + ], + "storageKey": null + }, + { + "kind": "ClientExtension", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__id", + "storageKey": null + } + ] + } + ], + "storageKey": "audits(first:10)" + }, + { + "alias": null, + "args": (v4/*: any*/), + "filters": [ + "orderBy" + ], + "handle": "connection", + "key": "AuditsPage_audits", + "kind": "LinkedHandle", + "name": "audits" + } + ], + "type": "Organization", + "abstractKey": null + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "1c53759e5b25eb390345fee12e536896", + "id": null, + "metadata": {}, + "name": "AuditGraphListQuery", + "operationKind": "query", + "text": "query AuditGraphListQuery(\n $organizationId: ID!\n) {\n node(id: $organizationId) {\n __typename\n ... on Organization {\n ...AuditsPageFragment\n }\n id\n }\n}\n\nfragment AuditsPageFragment on Organization {\n audits(first: 10) {\n edges {\n node {\n id\n validFrom\n validUntil\n report {\n id\n filename\n }\n state\n framework {\n id\n name\n }\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n" + } +}; +})(); + +(node as any).hash = "3a082303ae15c8982a08c3bae8312846"; + +export default node; diff --git a/apps/console/src/hooks/graph/__generated__/AuditGraphNodeQuery.graphql.ts b/apps/console/src/hooks/graph/__generated__/AuditGraphNodeQuery.graphql.ts new file mode 100644 index 000000000..a19040305 --- /dev/null +++ b/apps/console/src/hooks/graph/__generated__/AuditGraphNodeQuery.graphql.ts @@ -0,0 +1,278 @@ +/** + * @generated SignedSource<<597dc89a18faf5837517c12ab6046991>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +export type AuditState = "COMPLETED" | "IN_PROGRESS" | "NOT_STARTED" | "OUTDATED" | "REJECTED"; +export type AuditGraphNodeQuery$variables = { + auditId: string; +}; +export type AuditGraphNodeQuery$data = { + readonly node: { + readonly createdAt?: any; + readonly framework?: { + readonly id: string; + readonly name: string; + }; + readonly id?: string; + readonly organization?: { + readonly id: string; + readonly name: string; + }; + readonly report?: { + readonly createdAt: any; + readonly downloadUrl: string | null | undefined; + readonly filename: string; + readonly id: string; + readonly mimeType: string; + readonly size: number; + } | null | undefined; + readonly reportUrl?: string | null | undefined; + readonly state?: AuditState; + readonly updatedAt?: any; + readonly validFrom?: any | null | undefined; + readonly validUntil?: any | null | undefined; + }; +}; +export type AuditGraphNodeQuery = { + response: AuditGraphNodeQuery$data; + variables: AuditGraphNodeQuery$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "auditId" + } +], +v1 = [ + { + "kind": "Variable", + "name": "id", + "variableName": "auditId" + } +], +v2 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}, +v3 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "validFrom", + "storageKey": null +}, +v4 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "validUntil", + "storageKey": null +}, +v5 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "createdAt", + "storageKey": null +}, +v6 = { + "alias": null, + "args": null, + "concreteType": "Report", + "kind": "LinkedField", + "name": "report", + "plural": false, + "selections": [ + (v2/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "filename", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "mimeType", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "size", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "downloadUrl", + "storageKey": null + }, + (v5/*: any*/) + ], + "storageKey": null +}, +v7 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "reportUrl", + "storageKey": null +}, +v8 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "state", + "storageKey": null +}, +v9 = [ + (v2/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + } +], +v10 = { + "alias": null, + "args": null, + "concreteType": "Framework", + "kind": "LinkedField", + "name": "framework", + "plural": false, + "selections": (v9/*: any*/), + "storageKey": null +}, +v11 = { + "alias": null, + "args": null, + "concreteType": "Organization", + "kind": "LinkedField", + "name": "organization", + "plural": false, + "selections": (v9/*: any*/), + "storageKey": null +}, +v12 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "updatedAt", + "storageKey": null +}; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "AuditGraphNodeQuery", + "selections": [ + { + "alias": null, + "args": (v1/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "kind": "InlineFragment", + "selections": [ + (v2/*: any*/), + (v3/*: any*/), + (v4/*: any*/), + (v6/*: any*/), + (v7/*: any*/), + (v8/*: any*/), + (v10/*: any*/), + (v11/*: any*/), + (v5/*: any*/), + (v12/*: any*/) + ], + "type": "Audit", + "abstractKey": null + } + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "AuditGraphNodeQuery", + "selections": [ + { + "alias": null, + "args": (v1/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null + }, + (v2/*: any*/), + { + "kind": "InlineFragment", + "selections": [ + (v3/*: any*/), + (v4/*: any*/), + (v6/*: any*/), + (v7/*: any*/), + (v8/*: any*/), + (v10/*: any*/), + (v11/*: any*/), + (v5/*: any*/), + (v12/*: any*/) + ], + "type": "Audit", + "abstractKey": null + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "8cab4d1083ea5990e42dbec0b435b7bd", + "id": null, + "metadata": {}, + "name": "AuditGraphNodeQuery", + "operationKind": "query", + "text": "query AuditGraphNodeQuery(\n $auditId: ID!\n) {\n node(id: $auditId) {\n __typename\n ... on Audit {\n id\n validFrom\n validUntil\n report {\n id\n filename\n mimeType\n size\n downloadUrl\n createdAt\n }\n reportUrl\n state\n framework {\n id\n name\n }\n organization {\n id\n name\n }\n createdAt\n updatedAt\n }\n id\n }\n}\n" + } +}; +})(); + +(node as any).hash = "3263f3b8f244acf3c982464daa078f7b"; + +export default node; diff --git a/apps/console/src/hooks/graph/__generated__/AuditGraphUpdateMutation.graphql.ts b/apps/console/src/hooks/graph/__generated__/AuditGraphUpdateMutation.graphql.ts new file mode 100644 index 000000000..08edab12b --- /dev/null +++ b/apps/console/src/hooks/graph/__generated__/AuditGraphUpdateMutation.graphql.ts @@ -0,0 +1,188 @@ +/** + * @generated SignedSource<> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +export type AuditState = "COMPLETED" | "IN_PROGRESS" | "NOT_STARTED" | "OUTDATED" | "REJECTED"; +export type UpdateAuditInput = { + id: string; + state?: AuditState | null | undefined; + validFrom?: any | null | undefined; + validUntil?: any | null | undefined; +}; +export type AuditGraphUpdateMutation$variables = { + input: UpdateAuditInput; +}; +export type AuditGraphUpdateMutation$data = { + readonly updateAudit: { + readonly audit: { + readonly framework: { + readonly id: string; + readonly name: string; + }; + readonly id: string; + readonly report: { + readonly filename: string; + readonly id: string; + } | null | undefined; + readonly state: AuditState; + readonly updatedAt: any; + readonly validFrom: any | null | undefined; + readonly validUntil: any | null | undefined; + }; + }; +}; +export type AuditGraphUpdateMutation = { + response: AuditGraphUpdateMutation$data; + variables: AuditGraphUpdateMutation$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "input" + } +], +v1 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}, +v2 = [ + { + "alias": null, + "args": [ + { + "kind": "Variable", + "name": "input", + "variableName": "input" + } + ], + "concreteType": "UpdateAuditPayload", + "kind": "LinkedField", + "name": "updateAudit", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Audit", + "kind": "LinkedField", + "name": "audit", + "plural": false, + "selections": [ + (v1/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "validFrom", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "validUntil", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "Report", + "kind": "LinkedField", + "name": "report", + "plural": false, + "selections": [ + (v1/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "filename", + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "state", + "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 + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "updatedAt", + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } +]; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "AuditGraphUpdateMutation", + "selections": (v2/*: any*/), + "type": "Mutation", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "AuditGraphUpdateMutation", + "selections": (v2/*: any*/) + }, + "params": { + "cacheID": "afd98ba771c6c437c46c275655333eb6", + "id": null, + "metadata": {}, + "name": "AuditGraphUpdateMutation", + "operationKind": "mutation", + "text": "mutation AuditGraphUpdateMutation(\n $input: UpdateAuditInput!\n) {\n updateAudit(input: $input) {\n audit {\n id\n validFrom\n validUntil\n report {\n id\n filename\n }\n state\n framework {\n id\n name\n }\n updatedAt\n }\n }\n}\n" + } +}; +})(); + +(node as any).hash = "3ddd17832768611675505d76da1839a1"; + +export default node; diff --git a/apps/console/src/hooks/graph/__generated__/AuditGraphUploadReportMutation.graphql.ts b/apps/console/src/hooks/graph/__generated__/AuditGraphUploadReportMutation.graphql.ts new file mode 100644 index 000000000..49dec8191 --- /dev/null +++ b/apps/console/src/hooks/graph/__generated__/AuditGraphUploadReportMutation.graphql.ts @@ -0,0 +1,154 @@ +/** + * @generated SignedSource<<39001f4e110ade4633319d2e71f1377f>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +export type UploadAuditReportInput = { + auditId: string; + file: any; +}; +export type AuditGraphUploadReportMutation$variables = { + input: UploadAuditReportInput; +}; +export type AuditGraphUploadReportMutation$data = { + readonly uploadAuditReport: { + readonly audit: { + readonly id: string; + readonly report: { + readonly createdAt: any; + readonly downloadUrl: string | null | undefined; + readonly filename: string; + readonly id: string; + } | null | undefined; + readonly updatedAt: any; + }; + }; +}; +export type AuditGraphUploadReportMutation = { + response: AuditGraphUploadReportMutation$data; + variables: AuditGraphUploadReportMutation$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "input" + } +], +v1 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}, +v2 = [ + { + "alias": null, + "args": [ + { + "kind": "Variable", + "name": "input", + "variableName": "input" + } + ], + "concreteType": "UploadAuditReportPayload", + "kind": "LinkedField", + "name": "uploadAuditReport", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Audit", + "kind": "LinkedField", + "name": "audit", + "plural": false, + "selections": [ + (v1/*: any*/), + { + "alias": null, + "args": null, + "concreteType": "Report", + "kind": "LinkedField", + "name": "report", + "plural": false, + "selections": [ + (v1/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "filename", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "downloadUrl", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "createdAt", + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "updatedAt", + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } +]; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "AuditGraphUploadReportMutation", + "selections": (v2/*: any*/), + "type": "Mutation", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "AuditGraphUploadReportMutation", + "selections": (v2/*: any*/) + }, + "params": { + "cacheID": "05229f6e6fb7e64ceaf93c4bb8f144e6", + "id": null, + "metadata": {}, + "name": "AuditGraphUploadReportMutation", + "operationKind": "mutation", + "text": "mutation AuditGraphUploadReportMutation(\n $input: UploadAuditReportInput!\n) {\n uploadAuditReport(input: $input) {\n audit {\n id\n report {\n id\n filename\n downloadUrl\n createdAt\n }\n updatedAt\n }\n }\n}\n" + } +}; +})(); + +(node as any).hash = "1acff19bbb4a2e0eeca934cc90040eda"; + +export default node; diff --git a/apps/console/src/layouts/MainLayout.tsx b/apps/console/src/layouts/MainLayout.tsx index 7043742df..6c2d42b9a 100644 --- a/apps/console/src/layouts/MainLayout.tsx +++ b/apps/console/src/layouts/MainLayout.tsx @@ -9,6 +9,7 @@ import { IconInboxEmpty, IconPageTextLine, IconSettingsGear2, + IconCheckmark1, IconStore, IconTodo, IconListStack, @@ -131,6 +132,11 @@ export function MainLayout() { icon={IconListStack} to={`${prefix}/data`} /> + ; +}; + +export default function AuditDetailsPage(props: Props) { + const audit = usePreloadedQuery(auditNodeQuery, props.queryRef); + const auditEntry = audit.node; + const { __, dateFormat } = useTranslate(); + const organizationId = useOrganizationId(); + + if (!auditEntry || !auditEntry.id || !auditEntry.framework) { + return
{__("Audit not found")}
; + } + + const deleteAudit = useDeleteAudit( + { id: auditEntry.id!, framework: { name: auditEntry.framework!.name } }, + ConnectionHandler.getConnectionID(organizationId, "AuditsPage_audits") + ); + + const { control, formState, handleSubmit, register, reset } = useFormWithSchema(updateAuditSchema, { + defaultValues: { + validFrom: auditEntry.validFrom?.split('T')[0] || "", + validUntil: auditEntry.validUntil?.split('T')[0] || "", + state: auditEntry.state || "NOT_STARTED", + }, + }); + + const updateAudit = useUpdateAudit(); + const [uploadAuditReport, isUploading] = useUploadAuditReport(); + const deleteAuditReport = useDeleteAuditReport(); + const confirm = useConfirm(); + const { toast } = useToast(); + + const onSubmit = handleSubmit(async (formData) => { + if (!auditEntry.id) return; + + try { + const formatDatetime = (dateString?: string) => { + if (!dateString) return undefined; + return `${dateString}T00:00:00Z`; + }; + + await updateAudit({ + id: auditEntry.id, + validFrom: formatDatetime(formData.validFrom), + validUntil: formatDatetime(formData.validUntil), + state: formData.state, + }); + reset(formData); + toast({ + title: __("Success"), + description: __("Audit updated successfully"), + variant: "success", + }); + } catch (error) { + toast({ + title: __("Error"), + description: error instanceof Error ? error.message : __("Failed to update audit"), + variant: "error", + }); + } + }); + + const handleDeleteReport = () => { + if (!auditEntry.report || !auditEntry.id) return; + + confirm( + async () => { + await deleteAuditReport({ auditId: auditEntry.id! }); + }, + { + message: sprintf( + __( + 'This will permanently delete the audit report "%s". This action cannot be undone.' + ), + auditEntry.report.filename + ), + } + ); + }; + + return ( +
+ + +
+
+
{auditEntry.framework?.name}
+ + {getAuditStateLabel(__, auditEntry.state || "NOT_STARTED")} + +
+ + + {__("Delete")} + + +
+ +
+
+ + {auditStates.map((state) => ( + + ))} + + + + + + + + + + +
+ {formState.isDirty && ( + + )} +
+
+ + +
+

{__("Audit Report")}

+ + {auditEntry.report ? ( +
+
+
+ +
+

+ {auditEntry.report.filename} +

+
+ + {fileSize(__, auditEntry.report.size)} + + + {__("Uploaded")} {dateFormat(auditEntry.report.createdAt)} + +
+
+
+ + { + if (auditEntry.report?.downloadUrl) { + window.open(auditEntry.report.downloadUrl, '_blank'); + } + }} + icon={IconArrowInbox} + > + {__("Download")} + + + {__("Delete")} + + +
+
+ ) : ( +
+

+ {__("Upload the final audit report document (PDF recommended)")} +

+ { + if (files.length > 0 && auditEntry.id) { + await uploadAuditReport({ + auditId: auditEntry.id, + file: files[0], + }); + window.location.reload(); + } + }} + accept={{ + "application/pdf": [".pdf"], + "application/vnd.openxmlformats-officedocument.wordprocessingml.document": + [".docx"], + }} + maxSize={25} + /> +
+ )} +
+
+
+
+ ); +} diff --git a/apps/console/src/pages/organizations/audits/AuditsPage.tsx b/apps/console/src/pages/organizations/audits/AuditsPage.tsx new file mode 100644 index 000000000..9b3442a45 --- /dev/null +++ b/apps/console/src/pages/organizations/audits/AuditsPage.tsx @@ -0,0 +1,177 @@ +import { + Button, + IconPlusLarge, + PageHeader, + Thead, + Tbody, + Tr, + Th, + Td, + Badge, + ActionDropdown, + DropdownItem, + IconTrashCan, +} from "@probo/ui"; +import { useTranslate } from "@probo/i18n"; +import { usePageTitle } from "@probo/hooks"; +import { + graphql, + usePaginationFragment, + usePreloadedQuery, + type PreloadedQuery, +} from "react-relay"; +import { useOrganizationId } from "/hooks/useOrganizationId"; +import { CreateAuditDialog } from "./dialogs/CreateAuditDialog"; +import { useDeleteAudit, auditsQuery } from "../../../hooks/graph/AuditGraph"; +import type { AuditGraphListQuery } from "/hooks/graph/__generated__/AuditGraphListQuery.graphql"; +import type { NodeOf } from "/types"; +import { getAuditStateLabel, getAuditStateVariant } from "@probo/helpers"; +import type { + AuditsPageFragment$data, + AuditsPageFragment$key, +} from "./__generated__/AuditsPageFragment.graphql"; +import { SortableTable } from "/components/SortableTable"; + +const paginatedAuditsFragment = graphql` + fragment AuditsPageFragment on Organization + @refetchable(queryName: "AuditsListQuery") + @argumentDefinitions( + first: { type: "Int", defaultValue: 10 } + orderBy: { type: "AuditOrder", defaultValue: null } + after: { type: "CursorKey", defaultValue: null } + before: { type: "CursorKey", defaultValue: null } + last: { type: "Int", defaultValue: null } + ) { + audits( + first: $first + after: $after + last: $last + before: $before + orderBy: $orderBy + ) @connection(key: "AuditsPage_audits") { + __id + edges { + node { + id + validFrom + validUntil + report { + id + filename + } + state + framework { + id + name + } + createdAt + } + } + } + } +`; + +type AuditEntry = NodeOf; + +type Props = { + queryRef: PreloadedQuery; +}; + +export default function AuditsPage(props: Props) { + const { __ } = useTranslate(); + const organizationId = useOrganizationId(); + + const data = usePreloadedQuery(auditsQuery, props.queryRef); + const pagination = usePaginationFragment( + paginatedAuditsFragment, + data.node as AuditsPageFragment$key + ); + const audits = pagination.data.audits?.edges?.map((edge) => edge.node) ?? []; + const connectionId = pagination.data.audits.__id; + + usePageTitle(__("Audits")); + + return ( +
+ + + + + + + + + {__("Framework")} + {__("State")} + {__("Valid From")} + {__("Valid Until")} + {__("Report")} + + + + + {audits.map((entry) => ( + + ))} + + +
+ ); +} + +function AuditRow({ + entry, + connectionId, +}: { + entry: AuditEntry; + connectionId: string; +}) { + const organizationId = useOrganizationId(); + const { __, dateFormat } = useTranslate(); + const deleteAudit = useDeleteAudit(entry, connectionId); + + return ( + + {entry.framework?.name ?? __("Unknown Framework")} + + + {getAuditStateLabel(__, entry.state)} + + + {dateFormat(entry.validFrom, { year: "numeric", month: "short", day: "numeric" }) || __("Not set")} + {dateFormat(entry.validUntil, { year: "numeric", month: "short", day: "numeric" }) || __("Not set")} + + {entry.report ? ( +
+ {__("Uploaded")} +
+ ) : ( + {__("Not uploaded")} + )} + + + + + {__("Delete")} + + + + + ); +} diff --git a/apps/console/src/pages/organizations/audits/__generated__/AuditsListQuery.graphql.ts b/apps/console/src/pages/organizations/audits/__generated__/AuditsListQuery.graphql.ts new file mode 100644 index 000000000..3cf122cd8 --- /dev/null +++ b/apps/console/src/pages/organizations/audits/__generated__/AuditsListQuery.graphql.ts @@ -0,0 +1,368 @@ +/** + * @generated SignedSource<<273ddcd519e40c3d2af76944a1f93191>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; +export type AuditOrderField = "CREATED_AT" | "STATE" | "VALID_FROM" | "VALID_UNTIL"; +export type OrderDirection = "ASC" | "DESC"; +export type AuditOrder = { + direction: OrderDirection; + field: AuditOrderField; +}; +export type AuditsListQuery$variables = { + after?: any | null | undefined; + before?: any | null | undefined; + first?: number | null | undefined; + id: string; + last?: number | null | undefined; + orderBy?: AuditOrder | null | undefined; +}; +export type AuditsListQuery$data = { + readonly node: { + readonly " $fragmentSpreads": FragmentRefs<"AuditsPageFragment">; + }; +}; +export type AuditsListQuery = { + response: AuditsListQuery$data; + variables: AuditsListQuery$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "after" +}, +v1 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "before" +}, +v2 = { + "defaultValue": 10, + "kind": "LocalArgument", + "name": "first" +}, +v3 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "id" +}, +v4 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "last" +}, +v5 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "orderBy" +}, +v6 = [ + { + "kind": "Variable", + "name": "id", + "variableName": "id" + } +], +v7 = [ + { + "kind": "Variable", + "name": "after", + "variableName": "after" + }, + { + "kind": "Variable", + "name": "before", + "variableName": "before" + }, + { + "kind": "Variable", + "name": "first", + "variableName": "first" + }, + { + "kind": "Variable", + "name": "last", + "variableName": "last" + }, + { + "kind": "Variable", + "name": "orderBy", + "variableName": "orderBy" + } +], +v8 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null +}, +v9 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}; +return { + "fragment": { + "argumentDefinitions": [ + (v0/*: any*/), + (v1/*: any*/), + (v2/*: any*/), + (v3/*: any*/), + (v4/*: any*/), + (v5/*: any*/) + ], + "kind": "Fragment", + "metadata": null, + "name": "AuditsListQuery", + "selections": [ + { + "alias": null, + "args": (v6/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "args": (v7/*: any*/), + "kind": "FragmentSpread", + "name": "AuditsPageFragment" + } + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [ + (v0/*: any*/), + (v1/*: any*/), + (v2/*: any*/), + (v4/*: any*/), + (v5/*: any*/), + (v3/*: any*/) + ], + "kind": "Operation", + "name": "AuditsListQuery", + "selections": [ + { + "alias": null, + "args": (v6/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v8/*: any*/), + (v9/*: any*/), + { + "kind": "InlineFragment", + "selections": [ + { + "alias": null, + "args": (v7/*: any*/), + "concreteType": "AuditConnection", + "kind": "LinkedField", + "name": "audits", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "AuditEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Audit", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v9/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "validFrom", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "validUntil", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "Report", + "kind": "LinkedField", + "name": "report", + "plural": false, + "selections": [ + (v9/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "filename", + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "state", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "Framework", + "kind": "LinkedField", + "name": "framework", + "plural": false, + "selections": [ + (v9/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "createdAt", + "storageKey": null + }, + (v8/*: 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 + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "hasPreviousPage", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "startCursor", + "storageKey": null + } + ], + "storageKey": null + }, + { + "kind": "ClientExtension", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__id", + "storageKey": null + } + ] + } + ], + "storageKey": null + }, + { + "alias": null, + "args": (v7/*: any*/), + "filters": [ + "orderBy" + ], + "handle": "connection", + "key": "AuditsPage_audits", + "kind": "LinkedHandle", + "name": "audits" + } + ], + "type": "Organization", + "abstractKey": null + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "120524c1493bac68d36318259531f84e", + "id": null, + "metadata": {}, + "name": "AuditsListQuery", + "operationKind": "query", + "text": "query AuditsListQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 10\n $last: Int = null\n $orderBy: AuditOrder = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...AuditsPageFragment_sdb03\n id\n }\n}\n\nfragment AuditsPageFragment_sdb03 on Organization {\n audits(first: $first, after: $after, last: $last, before: $before, orderBy: $orderBy) {\n edges {\n node {\n id\n validFrom\n validUntil\n report {\n id\n filename\n }\n state\n framework {\n id\n name\n }\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n" + } +}; +})(); + +(node as any).hash = "ef15955eb51e30372c935dcc7dcd5099"; + +export default node; diff --git a/apps/console/src/pages/organizations/audits/__generated__/AuditsPageFragment.graphql.ts b/apps/console/src/pages/organizations/audits/__generated__/AuditsPageFragment.graphql.ts new file mode 100644 index 000000000..be8b15b7f --- /dev/null +++ b/apps/console/src/pages/organizations/audits/__generated__/AuditsPageFragment.graphql.ts @@ -0,0 +1,298 @@ +/** + * @generated SignedSource<<168c07116a618dbd9663e4072ec04139>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ReaderFragment } from 'relay-runtime'; +export type AuditState = "COMPLETED" | "IN_PROGRESS" | "NOT_STARTED" | "OUTDATED" | "REJECTED"; +import { FragmentRefs } from "relay-runtime"; +export type AuditsPageFragment$data = { + readonly audits: { + readonly __id: string; + readonly edges: ReadonlyArray<{ + readonly node: { + readonly createdAt: any; + readonly framework: { + readonly id: string; + readonly name: string; + }; + readonly id: string; + readonly report: { + readonly filename: string; + readonly id: string; + } | null | undefined; + readonly state: AuditState; + readonly validFrom: any | null | undefined; + readonly validUntil: any | null | undefined; + }; + }>; + }; + readonly id: string; + readonly " $fragmentType": "AuditsPageFragment"; +}; +export type AuditsPageFragment$key = { + readonly " $data"?: AuditsPageFragment$data; + readonly " $fragmentSpreads": FragmentRefs<"AuditsPageFragment">; +}; + +import AuditsListQuery_graphql from './AuditsListQuery.graphql'; + +const node: ReaderFragment = (function(){ +var v0 = [ + "audits" +], +v1 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}; +return { + "argumentDefinitions": [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "after" + }, + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "before" + }, + { + "defaultValue": 10, + "kind": "LocalArgument", + "name": "first" + }, + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "last" + }, + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "orderBy" + } + ], + "kind": "Fragment", + "metadata": { + "connection": [ + { + "count": null, + "cursor": null, + "direction": "bidirectional", + "path": (v0/*: any*/) + } + ], + "refetch": { + "connection": { + "forward": { + "count": "first", + "cursor": "after" + }, + "backward": { + "count": "last", + "cursor": "before" + }, + "path": (v0/*: any*/) + }, + "fragmentPathInResult": [ + "node" + ], + "operation": AuditsListQuery_graphql, + "identifierInfo": { + "identifierField": "id", + "identifierQueryVariableName": "id" + } + } + }, + "name": "AuditsPageFragment", + "selections": [ + { + "alias": "audits", + "args": [ + { + "kind": "Variable", + "name": "orderBy", + "variableName": "orderBy" + } + ], + "concreteType": "AuditConnection", + "kind": "LinkedField", + "name": "__AuditsPage_audits_connection", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "AuditEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Audit", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v1/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "validFrom", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "validUntil", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "Report", + "kind": "LinkedField", + "name": "report", + "plural": false, + "selections": [ + (v1/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "filename", + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "state", + "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 + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "createdAt", + "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 + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "hasPreviousPage", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "startCursor", + "storageKey": null + } + ], + "storageKey": null + }, + { + "kind": "ClientExtension", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__id", + "storageKey": null + } + ] + } + ], + "storageKey": null + }, + (v1/*: any*/) + ], + "type": "Organization", + "abstractKey": null +}; +})(); + +(node as any).hash = "ef15955eb51e30372c935dcc7dcd5099"; + +export default node; diff --git a/apps/console/src/pages/organizations/audits/dialogs/CreateAuditDialog.tsx b/apps/console/src/pages/organizations/audits/dialogs/CreateAuditDialog.tsx new file mode 100644 index 000000000..827bd9339 --- /dev/null +++ b/apps/console/src/pages/organizations/audits/dialogs/CreateAuditDialog.tsx @@ -0,0 +1,192 @@ +import { + Button, + Dialog, + DialogContent, + DialogFooter, + Field, + Option, + useDialogRef, + Breadcrumb, + Input, + Select, + useToast, +} from "@probo/ui"; +import { useTranslate } from "@probo/i18n"; +import z from "zod"; +import { useFormWithSchema } from "/hooks/useFormWithSchema"; +import { ControlledField } from "/components/form/ControlledField"; +import { useCreateAudit } from "/hooks/graph/AuditGraph"; +import { auditStates, getAuditStateLabel } from "@probo/helpers"; +import { useLazyLoadQuery } from "react-relay"; +import { graphql } from "relay-runtime"; +import { Suspense } from "react"; +import { Controller, type Control } from "react-hook-form"; +import type { CreateAuditDialogFrameworksQuery } from "./__generated__/CreateAuditDialogFrameworksQuery.graphql"; + +const frameworksQuery = graphql` + query CreateAuditDialogFrameworksQuery($organizationId: ID!) { + organization: node(id: $organizationId) { + ... on Organization { + frameworks(first: 100) { + edges { + node { + id + name + } + } + } + } + } + } +`; + +const schema = z.object({ + frameworkId: z.string().min(1, "Framework is required"), + validFrom: z.string().optional(), + validUntil: z.string().optional(), + state: z.enum(["NOT_STARTED", "IN_PROGRESS", "COMPLETED", "REJECTED", "OUTDATED"]), +}); + +type Props = { + children: React.ReactNode; + connection: string; + organizationId: string; +}; + +export function CreateAuditDialog({ + children, + connection, + organizationId, +}: Props) { + const { __ } = useTranslate(); + const { toast } = useToast(); + const { control, handleSubmit, register, formState, reset } = + useFormWithSchema(schema, { + defaultValues: { + frameworkId: "", + validFrom: "", + validUntil: "", + state: "NOT_STARTED", + }, + }); + const ref = useDialogRef(); + const createAudit = useCreateAudit(connection); + + const onSubmit = handleSubmit(async (data) => { + try { + // Convert date strings to datetime format + const formatDatetime = (dateString?: string) => { + if (!dateString) return undefined; + return `${dateString}T00:00:00Z`; + }; + + await createAudit({ + organizationId, + frameworkId: data.frameworkId, + validFrom: formatDatetime(data.validFrom), + validUntil: formatDatetime(data.validUntil), + state: data.state, + }); + ref.current?.close(); + reset(); + toast({ + title: __("Success"), + description: __("Audit created successfully"), + variant: "success", + }); + } catch (error) { + toast({ + title: __("Error"), + description: error instanceof Error ? error.message : __("Failed to create audit"), + variant: "error", + }); + } + }); + + return ( + } + > +
+ + + }> + + + + + + {auditStates.map((state) => ( + + ))} + + + + + + + + + + + + +
+
+ ); +} + +type FormSchema = z.infer; + +function FrameworkSelect({ + organizationId, + control, + name +}: { + organizationId: string; + control: Control; + name: keyof FormSchema; +}) { + const { __ } = useTranslate(); + const data = useLazyLoadQuery(frameworksQuery, { organizationId }); + const frameworks = data?.organization?.frameworks?.edges?.map((edge) => edge.node).filter((node): node is NonNullable => node !== null) ?? []; + + return ( + ( + + )} + /> + ); +} diff --git a/apps/console/src/pages/organizations/audits/dialogs/__generated__/CreateAuditDialogFrameworksQuery.graphql.ts b/apps/console/src/pages/organizations/audits/dialogs/__generated__/CreateAuditDialogFrameworksQuery.graphql.ts new file mode 100644 index 000000000..858d35e3e --- /dev/null +++ b/apps/console/src/pages/organizations/audits/dialogs/__generated__/CreateAuditDialogFrameworksQuery.graphql.ts @@ -0,0 +1,172 @@ +/** + * @generated SignedSource<> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +export type CreateAuditDialogFrameworksQuery$variables = { + organizationId: string; +}; +export type CreateAuditDialogFrameworksQuery$data = { + readonly organization: { + readonly frameworks?: { + readonly edges: ReadonlyArray<{ + readonly node: { + readonly id: string; + readonly name: string; + }; + }>; + }; + }; +}; +export type CreateAuditDialogFrameworksQuery = { + response: CreateAuditDialogFrameworksQuery$data; + variables: CreateAuditDialogFrameworksQuery$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "organizationId" + } +], +v1 = [ + { + "kind": "Variable", + "name": "id", + "variableName": "organizationId" + } +], +v2 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}, +v3 = { + "kind": "InlineFragment", + "selections": [ + { + "alias": null, + "args": [ + { + "kind": "Literal", + "name": "first", + "value": 100 + } + ], + "concreteType": "FrameworkConnection", + "kind": "LinkedField", + "name": "frameworks", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "FrameworkEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Framework", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v2/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": "frameworks(first:100)" + } + ], + "type": "Organization", + "abstractKey": null +}; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "CreateAuditDialogFrameworksQuery", + "selections": [ + { + "alias": "organization", + "args": (v1/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v3/*: any*/) + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "CreateAuditDialogFrameworksQuery", + "selections": [ + { + "alias": "organization", + "args": (v1/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null + }, + (v3/*: any*/), + (v2/*: any*/) + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "3b61e88adc92ac47ea6b5810a8d13f18", + "id": null, + "metadata": {}, + "name": "CreateAuditDialogFrameworksQuery", + "operationKind": "query", + "text": "query CreateAuditDialogFrameworksQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n frameworks(first: 100) {\n edges {\n node {\n id\n name\n }\n }\n }\n }\n id\n }\n}\n" + } +}; +})(); + +(node as any).hash = "ce9f84bb4e6e1e657cdf54bf8a3b4faa"; + +export default node; diff --git a/apps/console/src/pages/organizations/frameworks/dialogs/__generated__/FrameworkControlDialogCreateMutation.graphql.ts b/apps/console/src/pages/organizations/frameworks/dialogs/__generated__/FrameworkControlDialogCreateMutation.graphql.ts index 418f5126a..5d5a7f84a 100644 --- a/apps/console/src/pages/organizations/frameworks/dialogs/__generated__/FrameworkControlDialogCreateMutation.graphql.ts +++ b/apps/console/src/pages/organizations/frameworks/dialogs/__generated__/FrameworkControlDialogCreateMutation.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<5c976aa26b87b4f77dfcfeba71d3bbe3>> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -17,7 +17,7 @@ export type CreateControlInput = { frameworkId: string; name: string; sectionTitle: string; - status?: ControlStatus | null | undefined; + status: ControlStatus; }; export type FrameworkControlDialogCreateMutation$variables = { connections: ReadonlyArray; diff --git a/apps/console/src/routes.tsx b/apps/console/src/routes.tsx index 819e1b73c..01b26f2cc 100644 --- a/apps/console/src/routes.tsx +++ b/apps/console/src/routes.tsx @@ -27,6 +27,7 @@ import { PageError } from "./components/PageError.tsx"; import { taskRoutes } from "./routes/taskRoutes.ts"; import { dataRoutes } from "./routes/dataRoutes.ts"; import { assetRoutes } from "./routes/assetRoutes.ts"; +import { auditRoutes } from "./routes/auditRoutes.ts"; import { lazy } from "@probo/react-lazy"; /** @@ -134,6 +135,7 @@ const routes = [ ...taskRoutes, ...assetRoutes, ...dataRoutes, + ...auditRoutes, { path: "*", Component: PageError, diff --git a/apps/console/src/routes/auditRoutes.ts b/apps/console/src/routes/auditRoutes.ts new file mode 100644 index 000000000..6d3418e10 --- /dev/null +++ b/apps/console/src/routes/auditRoutes.ts @@ -0,0 +1,26 @@ +import { loadQuery } from "react-relay"; +import { relayEnvironment } from "/providers/RelayProviders"; +import { PageSkeleton } from "/components/skeletons/PageSkeleton"; +import { lazy } from "@probo/react-lazy"; +import { auditsQuery, auditNodeQuery } from "../hooks/graph/AuditGraph"; + +export const auditRoutes = [ + { + path: "audits", + fallback: PageSkeleton, + queryLoader: (params: Record) => + loadQuery(relayEnvironment, auditsQuery, { organizationId: params.organizationId }), + Component: lazy( + () => import("/pages/organizations/audits/AuditsPage") + ), + }, + { + path: "audits/:auditId", + fallback: PageSkeleton, + queryLoader: (params: Record) => + loadQuery(relayEnvironment, auditNodeQuery, { auditId: params.auditId }), + Component: lazy( + () => import("/pages/organizations/audits/AuditDetailsPage") + ), + }, +]; diff --git a/packages/helpers/src/audits.ts b/packages/helpers/src/audits.ts new file mode 100644 index 000000000..44ea5f438 --- /dev/null +++ b/packages/helpers/src/audits.ts @@ -0,0 +1,43 @@ +type Translator = (s: string) => string; + +export const auditStates = [ + "NOT_STARTED", + "IN_PROGRESS", + "COMPLETED", + "REJECTED", + "OUTDATED", +] as const; + +export function getAuditStateLabel(__: Translator, state: (typeof auditStates)[number]) { + switch (state) { + case "NOT_STARTED": + return __("Not Started"); + case "IN_PROGRESS": + return __("In Progress"); + case "COMPLETED": + return __("Completed"); + case "REJECTED": + return __("Rejected"); + case "OUTDATED": + return __("Outdated"); + default: + return __("Unknown"); + } +} + +export function getAuditStateVariant(state: (typeof auditStates)[number]) { + switch (state) { + case "NOT_STARTED": + return "neutral"; + case "IN_PROGRESS": + return "info"; + case "COMPLETED": + return "success"; + case "REJECTED": + return "danger"; + case "OUTDATED": + return "warning"; + default: + return "neutral"; + } +} diff --git a/packages/helpers/src/index.ts b/packages/helpers/src/index.ts index 58246ae9b..b96d20145 100644 --- a/packages/helpers/src/index.ts +++ b/packages/helpers/src/index.ts @@ -15,5 +15,6 @@ export { certificationCategoryLabel, certifications } from "./certifications"; export { availableFrameworks } from "./frameworks"; export { getDocumentTypeLabel, documentTypes } from "./documents"; export { getAssetTypeVariant, getCriticityVariant } from "./assets"; +export { getAuditStateLabel, getAuditStateVariant, auditStates } from "./audits"; export { promisifyMutation } from "./relay"; export { fileType, fileSize } from "./file"; diff --git a/pkg/coredata/audit.go b/pkg/coredata/audit.go new file mode 100644 index 000000000..f0f411665 --- /dev/null +++ b/pkg/coredata/audit.go @@ -0,0 +1,297 @@ +// 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" + "fmt" + "maps" + "time" + + "github.com/getprobo/probo/pkg/gid" + "github.com/getprobo/probo/pkg/page" + "github.com/jackc/pgx/v5" + "go.gearno.de/kit/pg" +) + +type ( + Audit struct { + ID gid.GID `db:"id"` + OrganizationID gid.GID `db:"organization_id"` + FrameworkID gid.GID `db:"framework_id"` + ReportID *gid.GID `db:"report_id"` + ValidFrom *time.Time `db:"valid_from"` + ValidUntil *time.Time `db:"valid_until"` + State AuditState `db:"state"` + CreatedAt time.Time `db:"created_at"` + UpdatedAt time.Time `db:"updated_at"` + } + + Audits []*Audit +) + +func (a *Audit) CursorKey(field AuditOrderField) page.CursorKey { + switch field { + case AuditOrderFieldCreatedAt: + return page.NewCursorKey(a.ID, a.CreatedAt) + case AuditOrderFieldValidFrom: + return page.NewCursorKey(a.ID, a.ValidFrom) + case AuditOrderFieldValidUntil: + return page.NewCursorKey(a.ID, a.ValidUntil) + case AuditOrderFieldState: + return page.NewCursorKey(a.ID, a.State) + } + + panic(fmt.Sprintf("unsupported order by: %s", field)) +} + +func (a *Audit) LoadByID( + ctx context.Context, + conn pg.Conn, + scope Scoper, + auditID gid.GID, +) error { + q := ` +SELECT + id, + organization_id, + framework_id, + report_id, + valid_from, + valid_until, + state, + created_at, + updated_at +FROM + audits +WHERE + %s + AND id = @audit_id +LIMIT 1; +` + + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.StrictNamedArgs{"audit_id": auditID} + maps.Copy(args, scope.SQLArguments()) + + rows, err := conn.Query(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot query audit: %w", err) + } + + audit, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[Audit]) + if err != nil { + return fmt.Errorf("cannot collect audit: %w", err) + } + + *a = audit + + return nil +} + +func (a *Audits) CountByOrganizationID( + ctx context.Context, + conn pg.Conn, + scope Scoper, + organizationID gid.GID, +) (int, error) { + q := ` +SELECT + COUNT(id) +FROM + audits +WHERE + %s + AND organization_id = @organization_id +` + + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.StrictNamedArgs{"organization_id": organizationID} + maps.Copy(args, scope.SQLArguments()) + + row := conn.QueryRow(ctx, q, args) + + var count int + err := row.Scan(&count) + if err != nil { + return 0, fmt.Errorf("cannot count audits: %w", err) + } + + return count, nil +} + +func (a *Audits) LoadByOrganizationID( + ctx context.Context, + conn pg.Conn, + scope Scoper, + organizationID gid.GID, + cursor *page.Cursor[AuditOrderField], +) error { + q := ` +SELECT + id, + organization_id, + framework_id, + report_id, + valid_from, + valid_until, + state, + created_at, + updated_at +FROM + audits +WHERE + %s + AND organization_id = @organization_id + AND %s +` + + q = fmt.Sprintf(q, scope.SQLFragment(), cursor.SQLFragment()) + + args := pgx.StrictNamedArgs{"organization_id": organizationID} + 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 audits: %w", err) + } + + audits, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[Audit]) + if err != nil { + return fmt.Errorf("cannot collect audits: %w", err) + } + + *a = audits + + return nil +} + +func (a *Audit) Insert( + ctx context.Context, + conn pg.Conn, + scope Scoper, +) error { + q := ` +INSERT INTO audits ( + id, + tenant_id, + organization_id, + framework_id, + report_id, + valid_from, + valid_until, + state, + created_at, + updated_at +) VALUES ( + @id, + @tenant_id, + @organization_id, + @framework_id, + @report_id, + @valid_from, + @valid_until, + @state, + @created_at, + @updated_at +) +` + + args := pgx.StrictNamedArgs{ + "id": a.ID, + "tenant_id": scope.GetTenantID(), + "organization_id": a.OrganizationID, + "framework_id": a.FrameworkID, + "report_id": a.ReportID, + "valid_from": a.ValidFrom, + "valid_until": a.ValidUntil, + "state": a.State, + "created_at": a.CreatedAt, + "updated_at": a.UpdatedAt, + } + + _, err := conn.Exec(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot insert audit: %w", err) + } + + return nil +} + +func (a *Audit) Update( + ctx context.Context, + conn pg.Conn, + scope Scoper, +) error { + q := ` +UPDATE audits +SET + report_id = @report_id, + valid_from = @valid_from, + valid_until = @valid_until, + state = @state, + updated_at = @updated_at +WHERE + %s + AND id = @id +` + + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.StrictNamedArgs{ + "id": a.ID, + "report_id": a.ReportID, + "valid_from": a.ValidFrom, + "valid_until": a.ValidUntil, + "state": a.State, + "updated_at": a.UpdatedAt, + } + maps.Copy(args, scope.SQLArguments()) + + _, err := conn.Exec(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot update audit: %w", err) + } + + return nil +} + +func (a *Audit) Delete( + ctx context.Context, + conn pg.Conn, + scope Scoper, +) error { + q := ` +DELETE FROM audits +WHERE + %s + AND id = @id +` + + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.StrictNamedArgs{"id": a.ID} + maps.Copy(args, scope.SQLArguments()) + + _, err := conn.Exec(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot delete audit: %w", err) + } + + return nil +} diff --git a/pkg/coredata/audit_order_field.go b/pkg/coredata/audit_order_field.go new file mode 100644 index 000000000..ac2829684 --- /dev/null +++ b/pkg/coredata/audit_order_field.go @@ -0,0 +1,53 @@ +// 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 ( + "fmt" +) + +type AuditOrderField string + +const ( + AuditOrderFieldCreatedAt AuditOrderField = "CREATED_AT" + AuditOrderFieldValidFrom AuditOrderField = "VALID_FROM" + AuditOrderFieldValidUntil AuditOrderField = "VALID_UNTIL" + AuditOrderFieldState AuditOrderField = "STATE" +) + +func (p AuditOrderField) Column() string { + return string(p) +} + +func (p AuditOrderField) String() string { + return string(p) +} + +func (p AuditOrderField) MarshalText() ([]byte, error) { + return []byte(p.String()), nil +} + +func (p *AuditOrderField) UnmarshalText(text []byte) error { + val := string(text) + switch val { + case string(AuditOrderFieldCreatedAt), + string(AuditOrderFieldValidFrom), + string(AuditOrderFieldValidUntil), + string(AuditOrderFieldState): + *p = AuditOrderField(val) + return nil + } + return fmt.Errorf("invalid AuditOrderField value: %q", val) +} diff --git a/pkg/coredata/audit_state.go b/pkg/coredata/audit_state.go new file mode 100644 index 000000000..6d07ff873 --- /dev/null +++ b/pkg/coredata/audit_state.go @@ -0,0 +1,66 @@ +// Copyright (c) 2025 Probo Inc . +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +package coredata + +import ( + "database/sql/driver" + "fmt" +) + +type AuditState string + +const ( + AuditStateNotStarted AuditState = "NOT_STARTED" + AuditStateInProgress AuditState = "IN_PROGRESS" + AuditStateCompleted AuditState = "COMPLETED" + AuditStateRejected AuditState = "REJECTED" + AuditStateOutdated AuditState = "OUTDATED" +) + +func (as AuditState) String() string { + return string(as) +} + +func (as *AuditState) Scan(value any) error { + var s string + switch v := value.(type) { + case string: + s = v + case []byte: + s = string(v) + default: + return fmt.Errorf("unsupported type for AuditState: %T", value) + } + + switch s { + case "NOT_STARTED": + *as = AuditStateNotStarted + case "IN_PROGRESS": + *as = AuditStateInProgress + case "COMPLETED": + *as = AuditStateCompleted + case "REJECTED": + *as = AuditStateRejected + case "OUTDATED": + *as = AuditStateOutdated + default: + return fmt.Errorf("invalid AuditState value: %q", s) + } + return nil +} + +func (as AuditState) Value() (driver.Value, error) { + return as.String(), nil +} diff --git a/pkg/coredata/entity_type_reg.go b/pkg/coredata/entity_type_reg.go index 2850b77ab..9c492db2c 100644 --- a/pkg/coredata/entity_type_reg.go +++ b/pkg/coredata/entity_type_reg.go @@ -35,4 +35,6 @@ const ( DocumentVersionSignatureEntityType AssetEntityType DatumEntityType + AuditEntityType + ReportEntityType ) diff --git a/pkg/coredata/migrations/20250722T151525Z.sql b/pkg/coredata/migrations/20250722T151525Z.sql new file mode 100644 index 000000000..c52ca8349 --- /dev/null +++ b/pkg/coredata/migrations/20250722T151525Z.sql @@ -0,0 +1,34 @@ +-- Create audit state enum +CREATE TYPE audit_state AS ENUM ( + 'NOT_STARTED', + 'IN_PROGRESS', + 'COMPLETED', + 'REJECTED', + 'OUTDATED' +); + +-- Create reports table +CREATE TABLE reports ( + id TEXT PRIMARY KEY, + tenant_id TEXT NOT NULL, + object_key TEXT NOT NULL, + mime_type TEXT NOT NULL, + filename TEXT NOT NULL, + size BIGINT NOT NULL, + created_at TIMESTAMP WITH TIME ZONE NOT NULL, + updated_at TIMESTAMP WITH TIME ZONE NOT NULL +); + +-- Create audits table +CREATE TABLE audits ( + id TEXT PRIMARY KEY, + tenant_id TEXT NOT NULL, + organization_id TEXT NOT NULL REFERENCES organizations(id) ON DELETE CASCADE, + framework_id TEXT NOT NULL REFERENCES frameworks(id) ON DELETE CASCADE, + report_id TEXT REFERENCES reports(id) ON DELETE SET NULL, + valid_from DATE, + valid_until DATE, + state audit_state NOT NULL, + created_at TIMESTAMP WITH TIME ZONE NOT NULL, + updated_at TIMESTAMP WITH TIME ZONE NOT NULL +); diff --git a/pkg/coredata/report.go b/pkg/coredata/report.go new file mode 100644 index 000000000..3d92dfdbb --- /dev/null +++ b/pkg/coredata/report.go @@ -0,0 +1,202 @@ +// 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" + "fmt" + "maps" + "time" + + "github.com/getprobo/probo/pkg/gid" + "github.com/getprobo/probo/pkg/page" + "github.com/jackc/pgx/v5" + "go.gearno.de/kit/pg" +) + +type ( + Report struct { + ID gid.GID `db:"id"` + ObjectKey string `db:"object_key"` + MimeType string `db:"mime_type"` + Filename string `db:"filename"` + Size int64 `db:"size"` + CreatedAt time.Time `db:"created_at"` + UpdatedAt time.Time `db:"updated_at"` + } + + Reports []*Report +) + +func (r *Report) LoadByID( + ctx context.Context, + conn pg.Conn, + scope Scoper, + reportID gid.GID, +) error { + q := ` +SELECT + id, + object_key, + mime_type, + filename, + size, + created_at, + updated_at +FROM + reports +WHERE + %s + AND id = @report_id +LIMIT 1; +` + + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.StrictNamedArgs{"report_id": reportID} + maps.Copy(args, scope.SQLArguments()) + + rows, err := conn.Query(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot query report: %w", err) + } + + report, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[Report]) + if err != nil { + return fmt.Errorf("cannot collect report: %w", err) + } + + *r = report + + return nil +} + +func (r *Report) Insert( + ctx context.Context, + conn pg.Conn, + scope Scoper, +) error { + q := ` +INSERT INTO reports ( + id, + tenant_id, + object_key, + mime_type, + filename, + size, + created_at, + updated_at +) VALUES ( + @id, + @tenant_id, + @object_key, + @mime_type, + @filename, + @size, + @created_at, + @updated_at +) +` + + args := pgx.StrictNamedArgs{ + "id": r.ID, + "tenant_id": scope.GetTenantID(), + "object_key": r.ObjectKey, + "mime_type": r.MimeType, + "filename": r.Filename, + "size": r.Size, + "created_at": r.CreatedAt, + "updated_at": r.UpdatedAt, + } + + _, err := conn.Exec(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot insert report: %w", err) + } + + return nil +} + +func (r *Report) Update( + ctx context.Context, + conn pg.Conn, + scope Scoper, +) error { + q := ` +UPDATE reports +SET + object_key = @object_key, + mime_type = @mime_type, + filename = @filename, + size = @size, + updated_at = @updated_at +WHERE + %s + AND id = @id +` + + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.StrictNamedArgs{ + "id": r.ID, + "object_key": r.ObjectKey, + "mime_type": r.MimeType, + "filename": r.Filename, + "size": r.Size, + "updated_at": r.UpdatedAt, + } + maps.Copy(args, scope.SQLArguments()) + + _, err := conn.Exec(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot update report: %w", err) + } + + return nil +} + +func (r *Report) Delete( + ctx context.Context, + conn pg.Conn, + scope Scoper, +) error { + q := ` +DELETE FROM reports +WHERE + %s + AND id = @id +` + + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.StrictNamedArgs{"id": r.ID} + maps.Copy(args, scope.SQLArguments()) + + _, err := conn.Exec(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot delete report: %w", err) + } + + return nil +} + +func (r *Report) CursorKey(orderBy ReportOrderField) page.CursorKey { + switch orderBy { + case ReportOrderFieldID: + return page.NewCursorKey(r.ID, r.ID) + default: + return page.NewCursorKey(r.ID, r.ID) + } +} diff --git a/pkg/coredata/report_order_field.go b/pkg/coredata/report_order_field.go new file mode 100644 index 000000000..99a4c7bb1 --- /dev/null +++ b/pkg/coredata/report_order_field.go @@ -0,0 +1,40 @@ +// 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 ( + ReportOrderField string +) + +const ( + ReportOrderFieldID ReportOrderField = "ID" +) + +func (p ReportOrderField) Column() string { + return string(p) +} + +func (p ReportOrderField) String() string { + return string(p) +} + +func (p ReportOrderField) MarshalText() ([]byte, error) { + return []byte(p.String()), nil +} + +func (p *ReportOrderField) UnmarshalText(text []byte) error { + *p = ReportOrderField(text) + return nil +} diff --git a/pkg/probo/audit_service.go b/pkg/probo/audit_service.go new file mode 100644 index 000000000..2cad2b91d --- /dev/null +++ b/pkg/probo/audit_service.go @@ -0,0 +1,336 @@ +// 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" + + "github.com/getprobo/probo/pkg/coredata" + "github.com/getprobo/probo/pkg/gid" + "github.com/getprobo/probo/pkg/page" + "go.gearno.de/kit/pg" +) + +type AuditService struct { + svc *TenantService +} + +type ( + CreateAuditRequest struct { + OrganizationID gid.GID + FrameworkID gid.GID + ValidFrom *time.Time + ValidUntil *time.Time + State *coredata.AuditState + } + + UpdateAuditRequest struct { + ID gid.GID + ValidFrom *time.Time + ValidUntil *time.Time + State *coredata.AuditState + } + + UpdateAuditStateRequest struct { + ID gid.GID + State coredata.AuditState + } + + UploadAuditReportRequest struct { + AuditID gid.GID + File File + } + + DeleteAuditReportRequest struct { + ID gid.GID + } +) + +func (s AuditService) Get( + ctx context.Context, + auditID gid.GID, +) (*coredata.Audit, error) { + audit := &coredata.Audit{} + + err := s.svc.pg.WithConn( + ctx, + func(conn pg.Conn) error { + return audit.LoadByID(ctx, conn, s.svc.scope, auditID) + }, + ) + + if err != nil { + return nil, err + } + + return audit, nil +} + +func (s *AuditService) Create( + ctx context.Context, + req *CreateAuditRequest, +) (*coredata.Audit, error) { + now := time.Now() + + audit := &coredata.Audit{ + ID: gid.New(s.svc.scope.GetTenantID(), coredata.AuditEntityType), + OrganizationID: req.OrganizationID, + FrameworkID: req.FrameworkID, + ValidFrom: req.ValidFrom, + ValidUntil: req.ValidUntil, + State: coredata.AuditStateNotStarted, + CreatedAt: now, + UpdatedAt: now, + } + + if req.State != nil { + audit.State = *req.State + } + + err := s.svc.pg.WithTx( + ctx, + func(conn pg.Conn) error { + organization := &coredata.Organization{} + if err := organization.LoadByID(ctx, conn, s.svc.scope, req.OrganizationID); err != nil { + return fmt.Errorf("cannot load organization: %w", err) + } + + framework := &coredata.Framework{} + if err := framework.LoadByID(ctx, conn, s.svc.scope, req.FrameworkID); err != nil { + return fmt.Errorf("cannot load framework: %w", err) + } + + if err := audit.Insert(ctx, conn, s.svc.scope); err != nil { + return fmt.Errorf("cannot insert audit: %w", err) + } + + return nil + }, + ) + + if err != nil { + return nil, err + } + + return audit, nil +} + +func (s *AuditService) Update( + ctx context.Context, + req *UpdateAuditRequest, +) (*coredata.Audit, error) { + audit := &coredata.Audit{} + + err := s.svc.pg.WithTx( + ctx, + func(conn pg.Conn) error { + if err := audit.LoadByID(ctx, conn, s.svc.scope, req.ID); err != nil { + return fmt.Errorf("cannot load audit: %w", err) + } + + if req.ValidFrom != nil { + audit.ValidFrom = req.ValidFrom + } + if req.ValidUntil != nil { + audit.ValidUntil = req.ValidUntil + } + if req.State != nil { + audit.State = *req.State + } + + audit.UpdatedAt = time.Now() + + if err := audit.Update(ctx, conn, s.svc.scope); err != nil { + return fmt.Errorf("cannot update audit: %w", err) + } + + return nil + }, + ) + + if err != nil { + return nil, err + } + + return audit, nil +} + +func (s AuditService) Delete( + ctx context.Context, + auditID gid.GID, +) error { + audit := coredata.Audit{ID: auditID} + return s.svc.pg.WithConn( + ctx, + func(conn pg.Conn) error { + err := audit.Delete(ctx, conn, s.svc.scope) + if err != nil { + return fmt.Errorf("cannot delete audit: %w", err) + } + return nil + }, + ) +} + +func (s AuditService) ListForOrganizationID( + ctx context.Context, + organizationID gid.GID, + cursor *page.Cursor[coredata.AuditOrderField], +) (*page.Page[*coredata.Audit, coredata.AuditOrderField], error) { + var audits coredata.Audits + + err := s.svc.pg.WithConn( + ctx, + func(conn pg.Conn) error { + err := audits.LoadByOrganizationID(ctx, conn, s.svc.scope, organizationID, cursor) + if err != nil { + return fmt.Errorf("cannot load audits: %w", err) + } + + return nil + }, + ) + + if err != nil { + return nil, err + } + + return page.NewPage(audits, cursor), nil +} + +func (s AuditService) CountForOrganizationID( + ctx context.Context, + organizationID gid.GID, +) (int, error) { + var count int + + err := s.svc.pg.WithConn( + ctx, + func(conn pg.Conn) (err error) { + audits := coredata.Audits{} + count, err = audits.CountByOrganizationID(ctx, conn, s.svc.scope, organizationID) + if err != nil { + return fmt.Errorf("cannot count audits: %w", err) + } + + return nil + }, + ) + + if err != nil { + return 0, err + } + + return count, nil +} + +func (s AuditService) UploadReport( + ctx context.Context, + req UploadAuditReportRequest, +) (*coredata.Audit, error) { + audit := &coredata.Audit{} + + err := s.svc.pg.WithTx( + ctx, + func(conn pg.Conn) error { + if err := audit.LoadByID(ctx, conn, s.svc.scope, req.AuditID); err != nil { + return fmt.Errorf("cannot load audit: %w", err) + } + + report, err := s.svc.Reports.Create(ctx, req.File) + if err != nil { + return fmt.Errorf("cannot create report: %w", err) + } + + audit.ReportID = &report.ID + audit.UpdatedAt = time.Now() + + if err := audit.Update(ctx, conn, s.svc.scope); err != nil { + return fmt.Errorf("cannot update audit: %w", err) + } + + return nil + }, + ) + + if err != nil { + return nil, err + } + + return audit, nil +} + +func (s AuditService) GenerateReportURL( + ctx context.Context, + auditID gid.GID, + expiresIn time.Duration, +) (*string, error) { + audit, err := s.Get(ctx, auditID) + if err != nil { + return nil, fmt.Errorf("cannot get audit: %w", err) + } + + if audit.ReportID == nil { + return nil, fmt.Errorf("audit has no report") + } + + url, err := s.svc.Reports.GenerateDownloadURL(ctx, *audit.ReportID, expiresIn) + if err != nil { + return nil, fmt.Errorf("cannot generate report download URL: %w", err) + } + + return url, nil +} + +func (s AuditService) DeleteReport( + ctx context.Context, + auditID gid.GID, +) (*coredata.Audit, error) { + audit := &coredata.Audit{} + + err := s.svc.pg.WithTx( + ctx, + func(conn pg.Conn) error { + if err := audit.LoadByID(ctx, conn, s.svc.scope, auditID); err != nil { + return fmt.Errorf("cannot load audit: %w", err) + } + + if audit.ReportID != nil { + report := &coredata.Report{ID: *audit.ReportID} + + if err := report.Delete(ctx, conn, s.svc.scope); err != nil { + return fmt.Errorf("cannot delete report: %w", err) + } + + audit.ReportID = nil + audit.UpdatedAt = time.Now() + + if err := audit.Update(ctx, conn, s.svc.scope); err != nil { + return fmt.Errorf("cannot update audit: %w", err) + } + } + + return nil + }, + ) + + if err != nil { + return nil, err + } + + return audit, nil +} diff --git a/pkg/probo/report_service.go b/pkg/probo/report_service.go new file mode 100644 index 000000000..a68a94511 --- /dev/null +++ b/pkg/probo/report_service.go @@ -0,0 +1,164 @@ +// 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" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/getprobo/probo/pkg/coredata" + "github.com/getprobo/probo/pkg/gid" + "go.gearno.de/crypto/uuid" + "go.gearno.de/kit/pg" +) + +type ReportService struct { + svc *TenantService +} + +func (s ReportService) Get( + ctx context.Context, + reportID gid.GID, +) (*coredata.Report, error) { + report := &coredata.Report{} + + err := s.svc.pg.WithConn( + ctx, + func(conn pg.Conn) error { + err := report.LoadByID(ctx, conn, s.svc.scope, reportID) + if err != nil { + return fmt.Errorf("cannot load report: %w", err) + } + + return nil + }, + ) + + if err != nil { + return nil, err + } + + return report, nil +} + +func (s ReportService) Create( + ctx context.Context, + file File, +) (*coredata.Report, error) { + reportID := gid.New(s.svc.scope.GetTenantID(), coredata.ReportEntityType) + now := time.Now() + + objectKey, err := uuid.NewV7() + if err != nil { + return nil, fmt.Errorf("cannot generate object key: %w", err) + } + + _, err = s.svc.s3.PutObject(ctx, &s3.PutObjectInput{ + Bucket: aws.String(s.svc.bucket), + Key: aws.String(objectKey.String()), + Body: file.Content, + ContentType: aws.String(file.ContentType), + Metadata: map[string]string{ + "report-id": reportID.String(), + }, + }) + if err != nil { + return nil, fmt.Errorf("cannot upload report to S3: %w", err) + } + + report := &coredata.Report{ + ID: reportID, + ObjectKey: objectKey.String(), + MimeType: file.ContentType, + Filename: file.Filename, + Size: file.Size, + CreatedAt: now, + UpdatedAt: now, + } + + err = s.svc.pg.WithConn(ctx, func(conn pg.Conn) error { + err := report.Insert(ctx, conn, s.svc.scope) + if err != nil { + return fmt.Errorf("cannot insert report: %w", err) + } + + return nil + }) + + if err != nil { + return nil, err + } + + return report, nil +} + +func (s ReportService) Delete( + ctx context.Context, + reportID gid.GID, +) error { + return s.svc.pg.WithTx(ctx, func(conn pg.Conn) error { + report := &coredata.Report{} + err := report.LoadByID(ctx, conn, s.svc.scope, reportID) + if err != nil { + return fmt.Errorf("cannot get report: %w", err) + } + + _, err = s.svc.s3.DeleteObject(ctx, &s3.DeleteObjectInput{ + Bucket: aws.String(s.svc.bucket), + Key: aws.String(report.ObjectKey), + }) + if err != nil { + return fmt.Errorf("cannot delete report from S3: %w", err) + } + + err = report.Delete(ctx, conn, s.svc.scope) + if err != nil { + return fmt.Errorf("cannot delete report: %w", err) + } + + return nil + }) +} + +func (s ReportService) GenerateDownloadURL( + ctx context.Context, + reportID gid.GID, + expiresIn time.Duration, +) (*string, error) { + report, err := s.Get(ctx, reportID) + if err != nil { + return nil, fmt.Errorf("cannot get report: %w", err) + } + + presignClient := s3.NewPresignClient(s.svc.s3) + + presignedReq, err := presignClient.PresignGetObject(ctx, &s3.GetObjectInput{ + Bucket: aws.String(s.svc.bucket), + Key: aws.String(report.ObjectKey), + ResponseCacheControl: aws.String("max-age=3600, public"), + ResponseContentType: aws.String(report.MimeType), + ResponseContentDisposition: aws.String(fmt.Sprintf("attachment; filename=\"%s\"", report.Filename)), + }, func(opts *s3.PresignOptions) { + opts.Expires = expiresIn + }) + if err != nil { + return nil, fmt.Errorf("cannot presign GetObject request: %w", err) + } + + return &presignedReq.URL, nil +} diff --git a/pkg/probo/service.go b/pkg/probo/service.go index 3a3fecdde..71de5bb49 100644 --- a/pkg/probo/service.go +++ b/pkg/probo/service.go @@ -63,6 +63,8 @@ type ( Connectors *ConnectorService Assets *AssetService Data *DatumService + Audits *AuditService + Reports *ReportService } ) @@ -140,5 +142,7 @@ func (s *Service) WithTenant(tenantID gid.TenantID) *TenantService { tenantService.Connectors = &ConnectorService{svc: tenantService} tenantService.Assets = &AssetService{svc: tenantService} tenantService.Data = &DatumService{svc: tenantService} + tenantService.Audits = &AuditService{svc: tenantService} + tenantService.Reports = &ReportService{svc: tenantService} return tenantService } diff --git a/pkg/server/api/console/v1/schema.graphql b/pkg/server/api/console/v1/schema.graphql index 319e0e081..f2dd1683f 100644 --- a/pkg/server/api/console/v1/schema.graphql +++ b/pkg/server/api/console/v1/schema.graphql @@ -127,6 +127,30 @@ enum RiskTreatment ) } +enum AuditState + @goModel(model: "github.com/getprobo/probo/pkg/coredata.AuditState") { + NOT_STARTED + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.AuditStateNotStarted" + ) + IN_PROGRESS + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.AuditStateInProgress" + ) + COMPLETED + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.AuditStateCompleted" + ) + REJECTED + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.AuditStateRejected" + ) + OUTDATED + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.AuditStateOutdated" + ) +} + # Order Field Enums enum UserOrderField @goModel(model: "github.com/getprobo/probo/pkg/coredata.UserOrderField") { @@ -521,6 +545,27 @@ enum ControlStatus value: "github.com/getprobo/probo/pkg/coredata.ControlStatusExcluded" ) } + +enum AuditOrderField + @goModel(model: "github.com/getprobo/probo/pkg/coredata.AuditOrderField") { + CREATED_AT + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.AuditOrderFieldCreatedAt" + ) + VALID_FROM + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.AuditOrderFieldValidFrom" + ) + VALID_UNTIL + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.AuditOrderFieldValidUntil" + ) + STATE + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.AuditOrderFieldState" + ) +} + # Input Types input UserOrder @goModel( @@ -594,6 +639,14 @@ input RiskOrder field: RiskOrderField! } +input AuditOrder + @goModel( + model: "github.com/getprobo/probo/pkg/server/api/console/v1/types.AuditOrderBy" + ) { + direction: OrderDirection! + field: AuditOrderField! +} + input EvidenceOrder @goModel( model: "github.com/getprobo/probo/pkg/server/api/console/v1/types.EvidenceOrderBy" @@ -755,6 +808,14 @@ type Organization implements Node { orderBy: DatumOrder ): DatumConnection! @goField(forceResolver: true) + audits( + first: Int + after: CursorKey + last: Int + before: CursorKey + orderBy: AuditOrder + ): AuditConnection! @goField(forceResolver: true) + createdAt: Datetime! updatedAt: Datetime! } @@ -1064,6 +1125,30 @@ type Risk implements Node { updatedAt: Datetime! } +type Audit implements Node { + id: ID! + organization: Organization! @goField(forceResolver: true) + framework: Framework! @goField(forceResolver: true) + validFrom: Datetime + validUntil: Datetime + report: Report @goField(forceResolver: true) + reportUrl: String @goField(forceResolver: true) + state: AuditState! + createdAt: Datetime! + updatedAt: Datetime! +} + +type Report implements Node { + id: ID! + objectKey: String! + mimeType: String! + filename: String! + size: Int! + downloadUrl: String @goField(forceResolver: true) + createdAt: Datetime! + updatedAt: Datetime! +} + type Session { id: ID! expiresAt: Datetime! @@ -1283,6 +1368,20 @@ type DatumEdge { node: Datum! } +type AuditConnection + @goModel( + model: "github.com/getprobo/probo/pkg/server/api/console/v1/types.AuditConnection" + ) { + totalCount: Int! @goField(forceResolver: true) + edges: [AuditEdge!]! + pageInfo: PageInfo! +} + +type AuditEdge { + cursor: CursorKey! + node: Audit! +} + # Root Types type Query { node(id: ID!): Node! @@ -1437,6 +1536,12 @@ type Mutation { createDatum(input: CreateDatumInput!): CreateDatumPayload! updateDatum(input: UpdateDatumInput!): UpdateDatumPayload! deleteDatum(input: DeleteDatumInput!): DeleteDatumPayload! + + createAudit(input: CreateAuditInput!): CreateAuditPayload! + updateAudit(input: UpdateAuditInput!): UpdateAuditPayload! + deleteAudit(input: DeleteAuditInput!): DeleteAuditPayload! + uploadAuditReport(input: UploadAuditReportInput!): UploadAuditReportPayload! + deleteAuditReport(input: DeleteAuditReportInput!): DeleteAuditReportPayload! } # Input Types @@ -1778,6 +1883,35 @@ input DeleteControlInput { controlId: ID! } +# Audit input types +input CreateAuditInput { + organizationId: ID! + frameworkId: ID! + validFrom: Datetime + validUntil: Datetime + state: AuditState +} + +input UpdateAuditInput { + id: ID! + validFrom: Datetime + validUntil: Datetime + state: AuditState +} + +input DeleteAuditInput { + auditId: ID! +} + +input UploadAuditReportInput { + auditId: ID! + file: Upload! +} + +input DeleteAuditReportInput { + auditId: ID! +} + # Payload Types type CreateOrganizationPayload { organizationEdge: OrganizationEdge! @@ -2354,3 +2488,23 @@ type UpdateDatumPayload { type DeleteDatumPayload { deletedDatumId: ID! } + +type CreateAuditPayload { + auditEdge: AuditEdge! +} + +type UpdateAuditPayload { + audit: Audit! +} + +type DeleteAuditPayload { + deletedAuditId: ID! +} + +type UploadAuditReportPayload { + audit: Audit! +} + +type DeleteAuditReportPayload { + audit: Audit! +} diff --git a/pkg/server/api/console/v1/schema/schema.go b/pkg/server/api/console/v1/schema/schema.go index bb9b3f84a..3bb883823 100644 --- a/pkg/server/api/console/v1/schema/schema.go +++ b/pkg/server/api/console/v1/schema/schema.go @@ -44,6 +44,8 @@ type Config struct { type ResolverRoot interface { Asset() AssetResolver AssetConnection() AssetConnectionResolver + Audit() AuditResolver + AuditConnection() AuditConnectionResolver Control() ControlResolver ControlConnection() ControlConnectionResolver Datum() DatumResolver @@ -62,6 +64,7 @@ type ResolverRoot interface { Organization() OrganizationResolver PeopleConnection() PeopleConnectionResolver Query() QueryResolver + Report() ReportResolver Risk() RiskResolver RiskConnection() RiskConnectionResolver Task() TaskResolver @@ -111,6 +114,30 @@ type ComplexityRoot struct { Task func(childComplexity int) int } + Audit struct { + CreatedAt func(childComplexity int) int + Framework func(childComplexity int) int + ID func(childComplexity int) int + Organization func(childComplexity int) int + Report func(childComplexity int) int + ReportURL func(childComplexity int) int + State func(childComplexity int) int + UpdatedAt func(childComplexity int) int + ValidFrom func(childComplexity int) int + ValidUntil func(childComplexity int) int + } + + AuditConnection struct { + Edges func(childComplexity int) int + PageInfo func(childComplexity int) int + TotalCount func(childComplexity int) int + } + + AuditEdge struct { + Cursor func(childComplexity int) int + Node func(childComplexity int) int + } + BulkPublishDocumentVersionsPayload struct { DocumentEdges func(childComplexity int) int DocumentVersionEdges func(childComplexity int) int @@ -175,6 +202,10 @@ type ComplexityRoot struct { AssetEdge func(childComplexity int) int } + CreateAuditPayload struct { + AuditEdge func(childComplexity int) int + } + CreateControlDocumentMappingPayload struct { ControlEdge func(childComplexity int) int DocumentEdge func(childComplexity int) int @@ -274,6 +305,14 @@ type ComplexityRoot struct { DeletedAssetID func(childComplexity int) int } + DeleteAuditPayload struct { + DeletedAuditID func(childComplexity int) int + } + + DeleteAuditReportPayload struct { + Audit func(childComplexity int) int + } + DeleteControlDocumentMappingPayload struct { DeletedControlID func(childComplexity int) int DeletedDocumentID func(childComplexity int) int @@ -520,6 +559,7 @@ type ComplexityRoot struct { CancelSignatureRequest func(childComplexity int, input types.CancelSignatureRequestInput) int ConfirmEmail func(childComplexity int, input types.ConfirmEmailInput) int CreateAsset func(childComplexity int, input types.CreateAssetInput) int + CreateAudit func(childComplexity int, input types.CreateAuditInput) int CreateControl func(childComplexity int, input types.CreateControlInput) int CreateControlDocumentMapping func(childComplexity int, input types.CreateControlDocumentMappingInput) int CreateControlMeasureMapping func(childComplexity int, input types.CreateControlMeasureMappingInput) int @@ -537,6 +577,8 @@ type ComplexityRoot struct { CreateVendor func(childComplexity int, input types.CreateVendorInput) int CreateVendorRiskAssessment func(childComplexity int, input types.CreateVendorRiskAssessmentInput) int DeleteAsset func(childComplexity int, input types.DeleteAssetInput) int + DeleteAudit func(childComplexity int, input types.DeleteAuditInput) int + DeleteAuditReport func(childComplexity int, input types.DeleteAuditReportInput) int DeleteControl func(childComplexity int, input types.DeleteControlInput) int DeleteControlDocumentMapping func(childComplexity int, input types.DeleteControlDocumentMappingInput) int DeleteControlMeasureMapping func(childComplexity int, input types.DeleteControlMeasureMappingInput) int @@ -566,6 +608,7 @@ type ComplexityRoot struct { SendSigningNotifications func(childComplexity int, input types.SendSigningNotificationsInput) int UnassignTask func(childComplexity int, input types.UnassignTaskInput) int UpdateAsset func(childComplexity int, input types.UpdateAssetInput) int + UpdateAudit func(childComplexity int, input types.UpdateAuditInput) int UpdateControl func(childComplexity int, input types.UpdateControlInput) int UpdateDatum func(childComplexity int, input types.UpdateDatumInput) int UpdateDocument func(childComplexity int, input types.UpdateDocumentInput) int @@ -577,6 +620,7 @@ type ComplexityRoot struct { UpdateRisk func(childComplexity int, input types.UpdateRiskInput) int UpdateTask func(childComplexity int, input types.UpdateTaskInput) int UpdateVendor func(childComplexity int, input types.UpdateVendorInput) int + UploadAuditReport func(childComplexity int, input types.UploadAuditReportInput) int UploadMeasureEvidence func(childComplexity int, input types.UploadMeasureEvidenceInput) int UploadTaskEvidence func(childComplexity int, input types.UploadTaskEvidenceInput) int UploadVendorComplianceReport func(childComplexity int, input types.UploadVendorComplianceReportInput) int @@ -584,6 +628,7 @@ type ComplexityRoot struct { Organization struct { Assets func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AssetOrderBy) int + Audits func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AuditOrderBy) int Connectors func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ConnectorOrder) int Controls func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) int CreatedAt func(childComplexity int) int @@ -657,6 +702,17 @@ type ComplexityRoot struct { Success func(childComplexity int) int } + Report struct { + CreatedAt func(childComplexity int) int + DownloadURL func(childComplexity int) int + Filename func(childComplexity int) int + ID func(childComplexity int) int + MimeType func(childComplexity int) int + ObjectKey func(childComplexity int) int + Size func(childComplexity int) int + UpdatedAt func(childComplexity int) int + } + RequestEvidencePayload struct { EvidenceEdge func(childComplexity int) int } @@ -741,6 +797,10 @@ type ComplexityRoot struct { Asset func(childComplexity int) int } + UpdateAuditPayload struct { + Audit func(childComplexity int) int + } + UpdateControlPayload struct { Control func(childComplexity int) int } @@ -785,6 +845,10 @@ type ComplexityRoot struct { Vendor func(childComplexity int) int } + UploadAuditReportPayload struct { + Audit func(childComplexity int) int + } + UploadMeasureEvidencePayload struct { EvidenceEdge func(childComplexity int) int } @@ -917,6 +981,16 @@ type AssetResolver interface { type AssetConnectionResolver interface { TotalCount(ctx context.Context, obj *types.AssetConnection) (int, error) } +type AuditResolver interface { + Organization(ctx context.Context, obj *types.Audit) (*types.Organization, error) + Framework(ctx context.Context, obj *types.Audit) (*types.Framework, error) + + Report(ctx context.Context, obj *types.Audit) (*types.Report, error) + ReportURL(ctx context.Context, obj *types.Audit) (*string, error) +} +type AuditConnectionResolver interface { + TotalCount(ctx context.Context, obj *types.AuditConnection) (int, error) +} type ControlResolver interface { Framework(ctx context.Context, obj *types.Control) (*types.Framework, error) Measures(ctx context.Context, obj *types.Control, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MeasureOrderBy, filter *types.MeasureFilter) (*types.MeasureConnection, error) @@ -1049,6 +1123,11 @@ type MutationResolver interface { CreateDatum(ctx context.Context, input types.CreateDatumInput) (*types.CreateDatumPayload, error) UpdateDatum(ctx context.Context, input types.UpdateDatumInput) (*types.UpdateDatumPayload, error) DeleteDatum(ctx context.Context, input types.DeleteDatumInput) (*types.DeleteDatumPayload, error) + CreateAudit(ctx context.Context, input types.CreateAuditInput) (*types.CreateAuditPayload, error) + UpdateAudit(ctx context.Context, input types.UpdateAuditInput) (*types.UpdateAuditPayload, error) + DeleteAudit(ctx context.Context, input types.DeleteAuditInput) (*types.DeleteAuditPayload, error) + UploadAuditReport(ctx context.Context, input types.UploadAuditReportInput) (*types.UploadAuditReportPayload, error) + DeleteAuditReport(ctx context.Context, input types.DeleteAuditReportInput) (*types.DeleteAuditReportPayload, error) } type OrganizationResolver interface { LogoURL(ctx context.Context, obj *types.Organization) (*string, error) @@ -1064,6 +1143,7 @@ type OrganizationResolver interface { Tasks(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TaskOrderBy) (*types.TaskConnection, error) Assets(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AssetOrderBy) (*types.AssetConnection, error) Data(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DatumOrderBy) (*types.DatumConnection, error) + Audits(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AuditOrderBy) (*types.AuditConnection, error) } type PeopleConnectionResolver interface { TotalCount(ctx context.Context, obj *types.PeopleConnection) (int, error) @@ -1072,6 +1152,9 @@ type QueryResolver interface { Node(ctx context.Context, id gid.GID) (types.Node, error) Viewer(ctx context.Context) (*types.Viewer, error) } +type ReportResolver interface { + DownloadURL(ctx context.Context, obj *types.Report) (*string, error) +} type RiskResolver interface { Owner(ctx context.Context, obj *types.Risk) (*types.People, error) Organization(ctx context.Context, obj *types.Risk) (*types.Organization, error) @@ -1268,6 +1351,111 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.AssignTaskPayload.Task(childComplexity), true + case "Audit.createdAt": + if e.complexity.Audit.CreatedAt == nil { + break + } + + return e.complexity.Audit.CreatedAt(childComplexity), true + + case "Audit.framework": + if e.complexity.Audit.Framework == nil { + break + } + + return e.complexity.Audit.Framework(childComplexity), true + + case "Audit.id": + if e.complexity.Audit.ID == nil { + break + } + + return e.complexity.Audit.ID(childComplexity), true + + case "Audit.organization": + if e.complexity.Audit.Organization == nil { + break + } + + return e.complexity.Audit.Organization(childComplexity), true + + case "Audit.report": + if e.complexity.Audit.Report == nil { + break + } + + return e.complexity.Audit.Report(childComplexity), true + + case "Audit.reportUrl": + if e.complexity.Audit.ReportURL == nil { + break + } + + return e.complexity.Audit.ReportURL(childComplexity), true + + case "Audit.state": + if e.complexity.Audit.State == nil { + break + } + + return e.complexity.Audit.State(childComplexity), true + + case "Audit.updatedAt": + if e.complexity.Audit.UpdatedAt == nil { + break + } + + return e.complexity.Audit.UpdatedAt(childComplexity), true + + case "Audit.validFrom": + if e.complexity.Audit.ValidFrom == nil { + break + } + + return e.complexity.Audit.ValidFrom(childComplexity), true + + case "Audit.validUntil": + if e.complexity.Audit.ValidUntil == nil { + break + } + + return e.complexity.Audit.ValidUntil(childComplexity), true + + case "AuditConnection.edges": + if e.complexity.AuditConnection.Edges == nil { + break + } + + return e.complexity.AuditConnection.Edges(childComplexity), true + + case "AuditConnection.pageInfo": + if e.complexity.AuditConnection.PageInfo == nil { + break + } + + return e.complexity.AuditConnection.PageInfo(childComplexity), true + + case "AuditConnection.totalCount": + if e.complexity.AuditConnection.TotalCount == nil { + break + } + + return e.complexity.AuditConnection.TotalCount(childComplexity), true + + case "AuditEdge.cursor": + if e.complexity.AuditEdge.Cursor == nil { + break + } + + return e.complexity.AuditEdge.Cursor(childComplexity), true + + case "AuditEdge.node": + if e.complexity.AuditEdge.Node == nil { + break + } + + return e.complexity.AuditEdge.Node(childComplexity), true + case "BulkPublishDocumentVersionsPayload.documentEdges": if e.complexity.BulkPublishDocumentVersionsPayload.DocumentEdges == nil { break @@ -1495,6 +1683,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.CreateAssetPayload.AssetEdge(childComplexity), true + case "CreateAuditPayload.auditEdge": + if e.complexity.CreateAuditPayload.AuditEdge == nil { + break + } + + return e.complexity.CreateAuditPayload.AuditEdge(childComplexity), true + case "CreateControlDocumentMappingPayload.controlEdge": if e.complexity.CreateControlDocumentMappingPayload.ControlEdge == nil { break @@ -1752,6 +1947,20 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.DeleteAssetPayload.DeletedAssetID(childComplexity), true + case "DeleteAuditPayload.deletedAuditId": + if e.complexity.DeleteAuditPayload.DeletedAuditID == nil { + break + } + + return e.complexity.DeleteAuditPayload.DeletedAuditID(childComplexity), true + + case "DeleteAuditReportPayload.audit": + if e.complexity.DeleteAuditReportPayload.Audit == nil { + break + } + + return e.complexity.DeleteAuditReportPayload.Audit(childComplexity), true + case "DeleteControlDocumentMappingPayload.deletedControlId": if e.complexity.DeleteControlDocumentMappingPayload.DeletedControlID == nil { break @@ -2702,6 +2911,18 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.Mutation.CreateAsset(childComplexity, args["input"].(types.CreateAssetInput)), true + case "Mutation.createAudit": + if e.complexity.Mutation.CreateAudit == nil { + break + } + + args, err := ec.field_Mutation_createAudit_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.CreateAudit(childComplexity, args["input"].(types.CreateAuditInput)), true + case "Mutation.createControl": if e.complexity.Mutation.CreateControl == nil { break @@ -2906,6 +3127,30 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.Mutation.DeleteAsset(childComplexity, args["input"].(types.DeleteAssetInput)), true + case "Mutation.deleteAudit": + if e.complexity.Mutation.DeleteAudit == nil { + break + } + + args, err := ec.field_Mutation_deleteAudit_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.DeleteAudit(childComplexity, args["input"].(types.DeleteAuditInput)), true + + case "Mutation.deleteAuditReport": + if e.complexity.Mutation.DeleteAuditReport == nil { + break + } + + args, err := ec.field_Mutation_deleteAuditReport_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.DeleteAuditReport(childComplexity, args["input"].(types.DeleteAuditReportInput)), true + case "Mutation.deleteControl": if e.complexity.Mutation.DeleteControl == nil { break @@ -3254,6 +3499,18 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.Mutation.UpdateAsset(childComplexity, args["input"].(types.UpdateAssetInput)), true + case "Mutation.updateAudit": + if e.complexity.Mutation.UpdateAudit == nil { + break + } + + args, err := ec.field_Mutation_updateAudit_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.UpdateAudit(childComplexity, args["input"].(types.UpdateAuditInput)), true + case "Mutation.updateControl": if e.complexity.Mutation.UpdateControl == nil { break @@ -3386,6 +3643,18 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.Mutation.UpdateVendor(childComplexity, args["input"].(types.UpdateVendorInput)), true + case "Mutation.uploadAuditReport": + if e.complexity.Mutation.UploadAuditReport == nil { + break + } + + args, err := ec.field_Mutation_uploadAuditReport_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.UploadAuditReport(childComplexity, args["input"].(types.UploadAuditReportInput)), true + case "Mutation.uploadMeasureEvidence": if e.complexity.Mutation.UploadMeasureEvidence == nil { break @@ -3434,6 +3703,18 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.Organization.Assets(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey), args["orderBy"].(*types.AssetOrderBy)), true + case "Organization.audits": + if e.complexity.Organization.Audits == nil { + break + } + + args, err := ec.field_Organization_audits_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Organization.Audits(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey), args["orderBy"].(*types.AuditOrderBy)), true + case "Organization.connectors": if e.complexity.Organization.Connectors == nil { break @@ -3802,6 +4083,62 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.RemoveUserPayload.Success(childComplexity), true + case "Report.createdAt": + if e.complexity.Report.CreatedAt == nil { + break + } + + return e.complexity.Report.CreatedAt(childComplexity), true + + case "Report.downloadUrl": + if e.complexity.Report.DownloadURL == nil { + break + } + + return e.complexity.Report.DownloadURL(childComplexity), true + + case "Report.filename": + if e.complexity.Report.Filename == nil { + break + } + + return e.complexity.Report.Filename(childComplexity), true + + case "Report.id": + if e.complexity.Report.ID == nil { + break + } + + return e.complexity.Report.ID(childComplexity), true + + case "Report.mimeType": + if e.complexity.Report.MimeType == nil { + break + } + + return e.complexity.Report.MimeType(childComplexity), true + + case "Report.objectKey": + if e.complexity.Report.ObjectKey == nil { + break + } + + return e.complexity.Report.ObjectKey(childComplexity), true + + case "Report.size": + if e.complexity.Report.Size == nil { + break + } + + return e.complexity.Report.Size(childComplexity), true + + case "Report.updatedAt": + if e.complexity.Report.UpdatedAt == nil { + break + } + + return e.complexity.Report.UpdatedAt(childComplexity), true + case "RequestEvidencePayload.evidenceEdge": if e.complexity.RequestEvidencePayload.EvidenceEdge == nil { break @@ -4158,6 +4495,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.UpdateAssetPayload.Asset(childComplexity), true + case "UpdateAuditPayload.audit": + if e.complexity.UpdateAuditPayload.Audit == nil { + break + } + + return e.complexity.UpdateAuditPayload.Audit(childComplexity), true + case "UpdateControlPayload.control": if e.complexity.UpdateControlPayload.Control == nil { break @@ -4235,6 +4579,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.UpdateVendorPayload.Vendor(childComplexity), true + case "UploadAuditReportPayload.audit": + if e.complexity.UploadAuditReportPayload.Audit == nil { + break + } + + return e.complexity.UploadAuditReportPayload.Audit(childComplexity), true + case "UploadMeasureEvidencePayload.evidenceEdge": if e.complexity.UploadMeasureEvidencePayload.EvidenceEdge == nil { break @@ -4770,6 +5121,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputAssessVendorInput, ec.unmarshalInputAssetOrder, ec.unmarshalInputAssignTaskInput, + ec.unmarshalInputAuditOrder, ec.unmarshalInputBulkPublishDocumentVersionsInput, ec.unmarshalInputBulkRequestSignaturesInput, ec.unmarshalInputCancelSignatureRequestInput, @@ -4778,6 +5130,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputControlFilter, ec.unmarshalInputControlOrder, ec.unmarshalInputCreateAssetInput, + ec.unmarshalInputCreateAuditInput, ec.unmarshalInputCreateControlDocumentMappingInput, ec.unmarshalInputCreateControlInput, ec.unmarshalInputCreateControlMeasureMappingInput, @@ -4797,6 +5150,8 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputCreateVendorRiskAssessmentInput, ec.unmarshalInputDatumOrder, ec.unmarshalInputDeleteAssetInput, + ec.unmarshalInputDeleteAuditInput, + ec.unmarshalInputDeleteAuditReportInput, ec.unmarshalInputDeleteControlDocumentMappingInput, ec.unmarshalInputDeleteControlInput, ec.unmarshalInputDeleteControlMeasureMappingInput, @@ -4840,6 +5195,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputTaskOrder, ec.unmarshalInputUnassignTaskInput, ec.unmarshalInputUpdateAssetInput, + ec.unmarshalInputUpdateAuditInput, ec.unmarshalInputUpdateControlInput, ec.unmarshalInputUpdateDatumInput, ec.unmarshalInputUpdateDocumentInput, @@ -4851,6 +5207,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputUpdateRiskInput, ec.unmarshalInputUpdateTaskInput, ec.unmarshalInputUpdateVendorInput, + ec.unmarshalInputUploadAuditReportInput, ec.unmarshalInputUploadMeasureEvidenceInput, ec.unmarshalInputUploadTaskEvidenceInput, ec.unmarshalInputUploadVendorComplianceReportInput, @@ -5084,6 +5441,30 @@ enum RiskTreatment ) } +enum AuditState + @goModel(model: "github.com/getprobo/probo/pkg/coredata.AuditState") { + NOT_STARTED + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.AuditStateNotStarted" + ) + IN_PROGRESS + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.AuditStateInProgress" + ) + COMPLETED + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.AuditStateCompleted" + ) + REJECTED + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.AuditStateRejected" + ) + OUTDATED + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.AuditStateOutdated" + ) +} + # Order Field Enums enum UserOrderField @goModel(model: "github.com/getprobo/probo/pkg/coredata.UserOrderField") { @@ -5478,6 +5859,27 @@ enum ControlStatus value: "github.com/getprobo/probo/pkg/coredata.ControlStatusExcluded" ) } + +enum AuditOrderField + @goModel(model: "github.com/getprobo/probo/pkg/coredata.AuditOrderField") { + CREATED_AT + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.AuditOrderFieldCreatedAt" + ) + VALID_FROM + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.AuditOrderFieldValidFrom" + ) + VALID_UNTIL + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.AuditOrderFieldValidUntil" + ) + STATE + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.AuditOrderFieldState" + ) +} + # Input Types input UserOrder @goModel( @@ -5551,6 +5953,14 @@ input RiskOrder field: RiskOrderField! } +input AuditOrder + @goModel( + model: "github.com/getprobo/probo/pkg/server/api/console/v1/types.AuditOrderBy" + ) { + direction: OrderDirection! + field: AuditOrderField! +} + input EvidenceOrder @goModel( model: "github.com/getprobo/probo/pkg/server/api/console/v1/types.EvidenceOrderBy" @@ -5712,6 +6122,14 @@ type Organization implements Node { orderBy: DatumOrder ): DatumConnection! @goField(forceResolver: true) + audits( + first: Int + after: CursorKey + last: Int + before: CursorKey + orderBy: AuditOrder + ): AuditConnection! @goField(forceResolver: true) + createdAt: Datetime! updatedAt: Datetime! } @@ -6021,6 +6439,30 @@ type Risk implements Node { updatedAt: Datetime! } +type Audit implements Node { + id: ID! + organization: Organization! @goField(forceResolver: true) + framework: Framework! @goField(forceResolver: true) + validFrom: Datetime + validUntil: Datetime + report: Report @goField(forceResolver: true) + reportUrl: String @goField(forceResolver: true) + state: AuditState! + createdAt: Datetime! + updatedAt: Datetime! +} + +type Report implements Node { + id: ID! + objectKey: String! + mimeType: String! + filename: String! + size: Int! + downloadUrl: String @goField(forceResolver: true) + createdAt: Datetime! + updatedAt: Datetime! +} + type Session { id: ID! expiresAt: Datetime! @@ -6240,6 +6682,20 @@ type DatumEdge { node: Datum! } +type AuditConnection + @goModel( + model: "github.com/getprobo/probo/pkg/server/api/console/v1/types.AuditConnection" + ) { + totalCount: Int! @goField(forceResolver: true) + edges: [AuditEdge!]! + pageInfo: PageInfo! +} + +type AuditEdge { + cursor: CursorKey! + node: Audit! +} + # Root Types type Query { node(id: ID!): Node! @@ -6394,6 +6850,12 @@ type Mutation { createDatum(input: CreateDatumInput!): CreateDatumPayload! updateDatum(input: UpdateDatumInput!): UpdateDatumPayload! deleteDatum(input: DeleteDatumInput!): DeleteDatumPayload! + + createAudit(input: CreateAuditInput!): CreateAuditPayload! + updateAudit(input: UpdateAuditInput!): UpdateAuditPayload! + deleteAudit(input: DeleteAuditInput!): DeleteAuditPayload! + uploadAuditReport(input: UploadAuditReportInput!): UploadAuditReportPayload! + deleteAuditReport(input: DeleteAuditReportInput!): DeleteAuditReportPayload! } # Input Types @@ -6735,6 +7197,35 @@ input DeleteControlInput { controlId: ID! } +# Audit input types +input CreateAuditInput { + organizationId: ID! + frameworkId: ID! + validFrom: Datetime + validUntil: Datetime + state: AuditState +} + +input UpdateAuditInput { + id: ID! + validFrom: Datetime + validUntil: Datetime + state: AuditState +} + +input DeleteAuditInput { + auditId: ID! +} + +input UploadAuditReportInput { + auditId: ID! + file: Upload! +} + +input DeleteAuditReportInput { + auditId: ID! +} + # Payload Types type CreateOrganizationPayload { organizationEdge: OrganizationEdge! @@ -7311,6 +7802,26 @@ type UpdateDatumPayload { type DeleteDatumPayload { deletedDatumId: ID! } + +type CreateAuditPayload { + auditEdge: AuditEdge! +} + +type UpdateAuditPayload { + audit: Audit! +} + +type DeleteAuditPayload { + deletedAuditId: ID! +} + +type UploadAuditReportPayload { + audit: Audit! +} + +type DeleteAuditReportPayload { + audit: Audit! +} `, BuiltIn: false}, } var parsedSchema = gqlparser.MustLoadSchema(sources...) @@ -8746,6 +9257,29 @@ func (ec *executionContext) field_Mutation_createAsset_argsInput( return zeroVal, nil } +func (ec *executionContext) field_Mutation_createAudit_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Mutation_createAudit_argsInput(ctx, rawArgs) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} +func (ec *executionContext) field_Mutation_createAudit_argsInput( + ctx context.Context, + rawArgs map[string]any, +) (types.CreateAuditInput, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + if tmp, ok := rawArgs["input"]; ok { + return ec.unmarshalNCreateAuditInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateAuditInput(ctx, tmp) + } + + var zeroVal types.CreateAuditInput + return zeroVal, nil +} + func (ec *executionContext) field_Mutation_createControlDocumentMapping_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -9137,6 +9671,52 @@ func (ec *executionContext) field_Mutation_deleteAsset_argsInput( return zeroVal, nil } +func (ec *executionContext) field_Mutation_deleteAuditReport_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Mutation_deleteAuditReport_argsInput(ctx, rawArgs) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} +func (ec *executionContext) field_Mutation_deleteAuditReport_argsInput( + ctx context.Context, + rawArgs map[string]any, +) (types.DeleteAuditReportInput, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + if tmp, ok := rawArgs["input"]; ok { + return ec.unmarshalNDeleteAuditReportInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteAuditReportInput(ctx, tmp) + } + + var zeroVal types.DeleteAuditReportInput + return zeroVal, nil +} + +func (ec *executionContext) field_Mutation_deleteAudit_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Mutation_deleteAudit_argsInput(ctx, rawArgs) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} +func (ec *executionContext) field_Mutation_deleteAudit_argsInput( + ctx context.Context, + rawArgs map[string]any, +) (types.DeleteAuditInput, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + if tmp, ok := rawArgs["input"]; ok { + return ec.unmarshalNDeleteAuditInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteAuditInput(ctx, tmp) + } + + var zeroVal types.DeleteAuditInput + return zeroVal, nil +} + func (ec *executionContext) field_Mutation_deleteControlDocumentMapping_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -9804,6 +10384,29 @@ func (ec *executionContext) field_Mutation_updateAsset_argsInput( return zeroVal, nil } +func (ec *executionContext) field_Mutation_updateAudit_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Mutation_updateAudit_argsInput(ctx, rawArgs) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} +func (ec *executionContext) field_Mutation_updateAudit_argsInput( + ctx context.Context, + rawArgs map[string]any, +) (types.UpdateAuditInput, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + if tmp, ok := rawArgs["input"]; ok { + return ec.unmarshalNUpdateAuditInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateAuditInput(ctx, tmp) + } + + var zeroVal types.UpdateAuditInput + return zeroVal, nil +} + func (ec *executionContext) field_Mutation_updateControl_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -10057,6 +10660,29 @@ func (ec *executionContext) field_Mutation_updateVendor_argsInput( return zeroVal, nil } +func (ec *executionContext) field_Mutation_uploadAuditReport_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Mutation_uploadAuditReport_argsInput(ctx, rawArgs) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} +func (ec *executionContext) field_Mutation_uploadAuditReport_argsInput( + ctx context.Context, + rawArgs map[string]any, +) (types.UploadAuditReportInput, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + if tmp, ok := rawArgs["input"]; ok { + return ec.unmarshalNUploadAuditReportInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUploadAuditReportInput(ctx, tmp) + } + + var zeroVal types.UploadAuditReportInput + return zeroVal, nil +} + func (ec *executionContext) field_Mutation_uploadMeasureEvidence_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -10221,6 +10847,101 @@ func (ec *executionContext) field_Organization_assets_argsOrderBy( return zeroVal, nil } +func (ec *executionContext) field_Organization_audits_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Organization_audits_argsFirst(ctx, rawArgs) + if err != nil { + return nil, err + } + args["first"] = arg0 + arg1, err := ec.field_Organization_audits_argsAfter(ctx, rawArgs) + if err != nil { + return nil, err + } + args["after"] = arg1 + arg2, err := ec.field_Organization_audits_argsLast(ctx, rawArgs) + if err != nil { + return nil, err + } + args["last"] = arg2 + arg3, err := ec.field_Organization_audits_argsBefore(ctx, rawArgs) + if err != nil { + return nil, err + } + args["before"] = arg3 + arg4, err := ec.field_Organization_audits_argsOrderBy(ctx, rawArgs) + if err != nil { + return nil, err + } + args["orderBy"] = arg4 + return args, nil +} +func (ec *executionContext) field_Organization_audits_argsFirst( + ctx context.Context, + rawArgs map[string]any, +) (*int, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("first")) + if tmp, ok := rawArgs["first"]; ok { + return ec.unmarshalOInt2ᚖint(ctx, tmp) + } + + var zeroVal *int + return zeroVal, nil +} + +func (ec *executionContext) field_Organization_audits_argsAfter( + ctx context.Context, + rawArgs map[string]any, +) (*page.CursorKey, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("after")) + if tmp, ok := rawArgs["after"]; ok { + return ec.unmarshalOCursorKey2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋpageᚐCursorKey(ctx, tmp) + } + + var zeroVal *page.CursorKey + return zeroVal, nil +} + +func (ec *executionContext) field_Organization_audits_argsLast( + ctx context.Context, + rawArgs map[string]any, +) (*int, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("last")) + if tmp, ok := rawArgs["last"]; ok { + return ec.unmarshalOInt2ᚖint(ctx, tmp) + } + + var zeroVal *int + return zeroVal, nil +} + +func (ec *executionContext) field_Organization_audits_argsBefore( + ctx context.Context, + rawArgs map[string]any, +) (*page.CursorKey, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("before")) + if tmp, ok := rawArgs["before"]; ok { + return ec.unmarshalOCursorKey2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋpageᚐCursorKey(ctx, tmp) + } + + var zeroVal *page.CursorKey + return zeroVal, nil +} + +func (ec *executionContext) field_Organization_audits_argsOrderBy( + ctx context.Context, + rawArgs map[string]any, +) (*types.AuditOrderBy, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("orderBy")) + if tmp, ok := rawArgs["orderBy"]; ok { + return ec.unmarshalOAuditOrder2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐAuditOrderBy(ctx, tmp) + } + + var zeroVal *types.AuditOrderBy + return zeroVal, nil +} + func (ec *executionContext) field_Organization_connectors_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -12782,6 +13503,8 @@ func (ec *executionContext) fieldContext_Asset_organization(_ context.Context, f return ec.fieldContext_Organization_assets(ctx, field) case "data": return ec.fieldContext_Organization_data(ctx, field) + case "audits": + return ec.fieldContext_Organization_audits(ctx, field) case "createdAt": return ec.fieldContext_Organization_createdAt(ctx, field) case "updatedAt": @@ -13211,6 +13934,764 @@ func (ec *executionContext) fieldContext_AssignTaskPayload_task(_ context.Contex return fc, nil } +func (ec *executionContext) _Audit_id(ctx context.Context, field graphql.CollectedField, obj *types.Audit) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Audit_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(gid.GID) + fc.Result = res + return ec.marshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Audit_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Audit", + 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) _Audit_organization(ctx context.Context, field graphql.CollectedField, obj *types.Audit) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Audit_organization(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Audit().Organization(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.Organization) + fc.Result = res + return ec.marshalNOrganization2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐOrganization(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Audit_organization(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Audit", + 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_Organization_id(ctx, field) + case "name": + return ec.fieldContext_Organization_name(ctx, field) + case "logoUrl": + return ec.fieldContext_Organization_logoUrl(ctx, field) + case "users": + return ec.fieldContext_Organization_users(ctx, field) + case "connectors": + return ec.fieldContext_Organization_connectors(ctx, field) + case "frameworks": + return ec.fieldContext_Organization_frameworks(ctx, field) + case "controls": + return ec.fieldContext_Organization_controls(ctx, field) + case "vendors": + return ec.fieldContext_Organization_vendors(ctx, field) + case "peoples": + return ec.fieldContext_Organization_peoples(ctx, field) + case "documents": + return ec.fieldContext_Organization_documents(ctx, field) + case "measures": + return ec.fieldContext_Organization_measures(ctx, field) + case "risks": + return ec.fieldContext_Organization_risks(ctx, field) + case "tasks": + return ec.fieldContext_Organization_tasks(ctx, field) + case "assets": + return ec.fieldContext_Organization_assets(ctx, field) + case "data": + return ec.fieldContext_Organization_data(ctx, field) + case "audits": + return ec.fieldContext_Organization_audits(ctx, field) + case "createdAt": + return ec.fieldContext_Organization_createdAt(ctx, field) + case "updatedAt": + return ec.fieldContext_Organization_updatedAt(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Organization", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Audit_framework(ctx context.Context, field graphql.CollectedField, obj *types.Audit) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Audit_framework(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Audit().Framework(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.Framework) + fc.Result = res + return ec.marshalNFramework2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐFramework(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Audit_framework(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Audit", + 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 "createdAt": + return ec.fieldContext_Framework_createdAt(ctx, field) + case "updatedAt": + return ec.fieldContext_Framework_updatedAt(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Framework", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Audit_validFrom(ctx context.Context, field graphql.CollectedField, obj *types.Audit) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Audit_validFrom(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ValidFrom, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*time.Time) + fc.Result = res + return ec.marshalODatetime2ᚖtimeᚐTime(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Audit_validFrom(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Audit", + 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) _Audit_validUntil(ctx context.Context, field graphql.CollectedField, obj *types.Audit) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Audit_validUntil(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ValidUntil, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*time.Time) + fc.Result = res + return ec.marshalODatetime2ᚖtimeᚐTime(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Audit_validUntil(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Audit", + 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) _Audit_report(ctx context.Context, field graphql.CollectedField, obj *types.Audit) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Audit_report(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Audit().Report(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*types.Report) + fc.Result = res + return ec.marshalOReport2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐReport(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Audit_report(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Audit", + 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_Report_id(ctx, field) + case "objectKey": + return ec.fieldContext_Report_objectKey(ctx, field) + case "mimeType": + return ec.fieldContext_Report_mimeType(ctx, field) + case "filename": + return ec.fieldContext_Report_filename(ctx, field) + case "size": + return ec.fieldContext_Report_size(ctx, field) + case "downloadUrl": + return ec.fieldContext_Report_downloadUrl(ctx, field) + case "createdAt": + return ec.fieldContext_Report_createdAt(ctx, field) + case "updatedAt": + return ec.fieldContext_Report_updatedAt(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Report", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Audit_reportUrl(ctx context.Context, field graphql.CollectedField, obj *types.Audit) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Audit_reportUrl(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Audit().ReportURL(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Audit_reportUrl(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Audit", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Audit_state(ctx context.Context, field graphql.CollectedField, obj *types.Audit) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Audit_state(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.State, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(coredata.AuditState) + fc.Result = res + return ec.marshalNAuditState2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditState(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Audit_state(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Audit", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type AuditState does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Audit_createdAt(ctx context.Context, field graphql.CollectedField, obj *types.Audit) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Audit_createdAt(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.CreatedAt, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(time.Time) + fc.Result = res + return ec.marshalNDatetime2timeᚐTime(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Audit_createdAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Audit", + 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) _Audit_updatedAt(ctx context.Context, field graphql.CollectedField, obj *types.Audit) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Audit_updatedAt(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.UpdatedAt, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(time.Time) + fc.Result = res + return ec.marshalNDatetime2timeᚐTime(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Audit_updatedAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Audit", + 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) _AuditConnection_totalCount(ctx context.Context, field graphql.CollectedField, obj *types.AuditConnection) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_AuditConnection_totalCount(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.AuditConnection().TotalCount(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_AuditConnection_totalCount(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "AuditConnection", + Field: field, + IsMethod: true, + IsResolver: true, + 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) _AuditConnection_edges(ctx context.Context, field graphql.CollectedField, obj *types.AuditConnection) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_AuditConnection_edges(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Edges, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*types.AuditEdge) + fc.Result = res + return ec.marshalNAuditEdge2ᚕᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐAuditEdgeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_AuditConnection_edges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "AuditConnection", + 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_AuditEdge_cursor(ctx, field) + case "node": + return ec.fieldContext_AuditEdge_node(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type AuditEdge", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _AuditConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *types.AuditConnection) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_AuditConnection_pageInfo(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.PageInfo, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(types.PageInfo) + fc.Result = res + return ec.marshalNPageInfo2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐPageInfo(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_AuditConnection_pageInfo(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "AuditConnection", + 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) _AuditEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *types.AuditEdge) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_AuditEdge_cursor(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Cursor, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(page.CursorKey) + fc.Result = res + return ec.marshalNCursorKey2githubᚗcomᚋgetproboᚋproboᚋpkgᚋpageᚐCursorKey(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_AuditEdge_cursor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "AuditEdge", + 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) _AuditEdge_node(ctx context.Context, field graphql.CollectedField, obj *types.AuditEdge) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_AuditEdge_node(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Node, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.Audit) + fc.Result = res + return ec.marshalNAudit2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐAudit(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_AuditEdge_node(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "AuditEdge", + 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_Audit_id(ctx, field) + case "organization": + return ec.fieldContext_Audit_organization(ctx, field) + case "framework": + return ec.fieldContext_Audit_framework(ctx, field) + case "validFrom": + return ec.fieldContext_Audit_validFrom(ctx, field) + case "validUntil": + return ec.fieldContext_Audit_validUntil(ctx, field) + case "report": + return ec.fieldContext_Audit_report(ctx, field) + case "reportUrl": + return ec.fieldContext_Audit_reportUrl(ctx, field) + case "state": + return ec.fieldContext_Audit_state(ctx, field) + case "createdAt": + return ec.fieldContext_Audit_createdAt(ctx, field) + case "updatedAt": + return ec.fieldContext_Audit_updatedAt(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Audit", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _BulkPublishDocumentVersionsPayload_documentVersionEdges(ctx context.Context, field graphql.CollectedField, obj *types.BulkPublishDocumentVersionsPayload) (ret graphql.Marshaler) { fc, err := ec.fieldContext_BulkPublishDocumentVersionsPayload_documentVersionEdges(ctx, field) if err != nil { @@ -14718,6 +16199,56 @@ func (ec *executionContext) fieldContext_CreateAssetPayload_assetEdge(_ context. return fc, nil } +func (ec *executionContext) _CreateAuditPayload_auditEdge(ctx context.Context, field graphql.CollectedField, obj *types.CreateAuditPayload) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_CreateAuditPayload_auditEdge(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.AuditEdge, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.AuditEdge) + fc.Result = res + return ec.marshalNAuditEdge2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐAuditEdge(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_CreateAuditPayload_auditEdge(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CreateAuditPayload", + 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_AuditEdge_cursor(ctx, field) + case "node": + return ec.fieldContext_AuditEdge_node(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type AuditEdge", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _CreateControlDocumentMappingPayload_controlEdge(ctx context.Context, field graphql.CollectedField, obj *types.CreateControlDocumentMappingPayload) (ret graphql.Marshaler) { fc, err := ec.fieldContext_CreateControlDocumentMappingPayload_controlEdge(ctx, field) if err != nil { @@ -16148,6 +17679,8 @@ func (ec *executionContext) fieldContext_Datum_organization(_ context.Context, f return ec.fieldContext_Organization_assets(ctx, field) case "data": return ec.fieldContext_Organization_data(ctx, field) + case "audits": + return ec.fieldContext_Organization_audits(ctx, field) case "createdAt": return ec.fieldContext_Organization_createdAt(ctx, field) case "updatedAt": @@ -16545,6 +18078,116 @@ func (ec *executionContext) fieldContext_DeleteAssetPayload_deletedAssetId(_ con return fc, nil } +func (ec *executionContext) _DeleteAuditPayload_deletedAuditId(ctx context.Context, field graphql.CollectedField, obj *types.DeleteAuditPayload) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_DeleteAuditPayload_deletedAuditId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeletedAuditID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(gid.GID) + fc.Result = res + return ec.marshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_DeleteAuditPayload_deletedAuditId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "DeleteAuditPayload", + 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) _DeleteAuditReportPayload_audit(ctx context.Context, field graphql.CollectedField, obj *types.DeleteAuditReportPayload) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_DeleteAuditReportPayload_audit(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Audit, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.Audit) + fc.Result = res + return ec.marshalNAudit2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐAudit(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_DeleteAuditReportPayload_audit(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "DeleteAuditReportPayload", + 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_Audit_id(ctx, field) + case "organization": + return ec.fieldContext_Audit_organization(ctx, field) + case "framework": + return ec.fieldContext_Audit_framework(ctx, field) + case "validFrom": + return ec.fieldContext_Audit_validFrom(ctx, field) + case "validUntil": + return ec.fieldContext_Audit_validUntil(ctx, field) + case "report": + return ec.fieldContext_Audit_report(ctx, field) + case "reportUrl": + return ec.fieldContext_Audit_reportUrl(ctx, field) + case "state": + return ec.fieldContext_Audit_state(ctx, field) + case "createdAt": + return ec.fieldContext_Audit_createdAt(ctx, field) + case "updatedAt": + return ec.fieldContext_Audit_updatedAt(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Audit", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _DeleteControlDocumentMappingPayload_deletedControlId(ctx context.Context, field graphql.CollectedField, obj *types.DeleteControlDocumentMappingPayload) (ret graphql.Marshaler) { fc, err := ec.fieldContext_DeleteControlDocumentMappingPayload_deletedControlId(ctx, field) if err != nil { @@ -17733,6 +19376,8 @@ func (ec *executionContext) fieldContext_Document_organization(_ context.Context return ec.fieldContext_Organization_assets(ctx, field) case "data": return ec.fieldContext_Organization_data(ctx, field) + case "audits": + return ec.fieldContext_Organization_audits(ctx, field) case "createdAt": return ec.fieldContext_Organization_createdAt(ctx, field) case "updatedAt": @@ -20886,6 +22531,8 @@ func (ec *executionContext) fieldContext_Framework_organization(_ context.Contex return ec.fieldContext_Organization_assets(ctx, field) case "data": return ec.fieldContext_Organization_data(ctx, field) + case "audits": + return ec.fieldContext_Organization_audits(ctx, field) case "createdAt": return ec.fieldContext_Organization_createdAt(ctx, field) case "updatedAt": @@ -26377,6 +28024,301 @@ func (ec *executionContext) fieldContext_Mutation_deleteDatum(ctx context.Contex return fc, nil } +func (ec *executionContext) _Mutation_createAudit(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_createAudit(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().CreateAudit(rctx, fc.Args["input"].(types.CreateAuditInput)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.CreateAuditPayload) + fc.Result = res + return ec.marshalNCreateAuditPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateAuditPayload(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_createAudit(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 "auditEdge": + return ec.fieldContext_CreateAuditPayload_auditEdge(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type CreateAuditPayload", 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_createAudit_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Mutation_updateAudit(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_updateAudit(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().UpdateAudit(rctx, fc.Args["input"].(types.UpdateAuditInput)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.UpdateAuditPayload) + fc.Result = res + return ec.marshalNUpdateAuditPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateAuditPayload(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_updateAudit(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 "audit": + return ec.fieldContext_UpdateAuditPayload_audit(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type UpdateAuditPayload", 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_updateAudit_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Mutation_deleteAudit(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_deleteAudit(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().DeleteAudit(rctx, fc.Args["input"].(types.DeleteAuditInput)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.DeleteAuditPayload) + fc.Result = res + return ec.marshalNDeleteAuditPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteAuditPayload(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_deleteAudit(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 "deletedAuditId": + return ec.fieldContext_DeleteAuditPayload_deletedAuditId(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type DeleteAuditPayload", 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_deleteAudit_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Mutation_uploadAuditReport(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_uploadAuditReport(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().UploadAuditReport(rctx, fc.Args["input"].(types.UploadAuditReportInput)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.UploadAuditReportPayload) + fc.Result = res + return ec.marshalNUploadAuditReportPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUploadAuditReportPayload(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_uploadAuditReport(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 "audit": + return ec.fieldContext_UploadAuditReportPayload_audit(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type UploadAuditReportPayload", 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_uploadAuditReport_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Mutation_deleteAuditReport(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_deleteAuditReport(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().DeleteAuditReport(rctx, fc.Args["input"].(types.DeleteAuditReportInput)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.DeleteAuditReportPayload) + fc.Result = res + return ec.marshalNDeleteAuditReportPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteAuditReportPayload(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_deleteAuditReport(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 "audit": + return ec.fieldContext_DeleteAuditReportPayload_audit(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type DeleteAuditReportPayload", 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_deleteAuditReport_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _Organization_id(ctx context.Context, field graphql.CollectedField, obj *types.Organization) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Organization_id(ctx, field) if err != nil { @@ -27258,6 +29200,69 @@ func (ec *executionContext) fieldContext_Organization_data(ctx context.Context, return fc, nil } +func (ec *executionContext) _Organization_audits(ctx context.Context, field graphql.CollectedField, obj *types.Organization) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Organization_audits(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Organization().Audits(rctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*page.CursorKey), fc.Args["last"].(*int), fc.Args["before"].(*page.CursorKey), fc.Args["orderBy"].(*types.AuditOrderBy)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.AuditConnection) + fc.Result = res + return ec.marshalNAuditConnection2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐAuditConnection(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Organization_audits(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Organization", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "totalCount": + return ec.fieldContext_AuditConnection_totalCount(ctx, field) + case "edges": + return ec.fieldContext_AuditConnection_edges(ctx, field) + case "pageInfo": + return ec.fieldContext_AuditConnection_pageInfo(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type AuditConnection", 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_Organization_audits_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _Organization_createdAt(ctx context.Context, field graphql.CollectedField, obj *types.Organization) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Organization_createdAt(ctx, field) if err != nil { @@ -27563,6 +29568,8 @@ func (ec *executionContext) fieldContext_OrganizationEdge_node(_ context.Context return ec.fieldContext_Organization_assets(ctx, field) case "data": return ec.fieldContext_Organization_data(ctx, field) + case "audits": + return ec.fieldContext_Organization_audits(ctx, field) case "createdAt": return ec.fieldContext_Organization_createdAt(ctx, field) case "updatedAt": @@ -28855,6 +30862,355 @@ func (ec *executionContext) fieldContext_RemoveUserPayload_success(_ context.Con return fc, nil } +func (ec *executionContext) _Report_id(ctx context.Context, field graphql.CollectedField, obj *types.Report) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Report_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(gid.GID) + fc.Result = res + return ec.marshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Report_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Report", + 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) _Report_objectKey(ctx context.Context, field graphql.CollectedField, obj *types.Report) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Report_objectKey(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ObjectKey, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Report_objectKey(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Report", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Report_mimeType(ctx context.Context, field graphql.CollectedField, obj *types.Report) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Report_mimeType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.MimeType, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Report_mimeType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Report", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Report_filename(ctx context.Context, field graphql.CollectedField, obj *types.Report) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Report_filename(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Filename, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Report_filename(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Report", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Report_size(ctx context.Context, field graphql.CollectedField, obj *types.Report) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Report_size(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Size, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Report_size(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Report", + 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) _Report_downloadUrl(ctx context.Context, field graphql.CollectedField, obj *types.Report) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Report_downloadUrl(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Report().DownloadURL(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Report_downloadUrl(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Report", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Report_createdAt(ctx context.Context, field graphql.CollectedField, obj *types.Report) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Report_createdAt(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.CreatedAt, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(time.Time) + fc.Result = res + return ec.marshalNDatetime2timeᚐTime(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Report_createdAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Report", + 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) _Report_updatedAt(ctx context.Context, field graphql.CollectedField, obj *types.Report) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Report_updatedAt(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.UpdatedAt, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(time.Time) + fc.Result = res + return ec.marshalNDatetime2timeᚐTime(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Report_updatedAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Report", + 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) _RequestEvidencePayload_evidenceEdge(ctx context.Context, field graphql.CollectedField, obj *types.RequestEvidencePayload) (ret graphql.Marshaler) { fc, err := ec.fieldContext_RequestEvidencePayload_evidenceEdge(ctx, field) if err != nil { @@ -29615,6 +31971,8 @@ func (ec *executionContext) fieldContext_Risk_organization(_ context.Context, fi return ec.fieldContext_Organization_assets(ctx, field) case "data": return ec.fieldContext_Organization_data(ctx, field) + case "audits": + return ec.fieldContext_Organization_audits(ctx, field) case "createdAt": return ec.fieldContext_Organization_createdAt(ctx, field) case "updatedAt": @@ -30701,6 +33059,8 @@ func (ec *executionContext) fieldContext_Task_organization(_ context.Context, fi return ec.fieldContext_Organization_assets(ctx, field) case "data": return ec.fieldContext_Organization_data(ctx, field) + case "audits": + return ec.fieldContext_Organization_audits(ctx, field) case "createdAt": return ec.fieldContext_Organization_createdAt(ctx, field) case "updatedAt": @@ -31328,6 +33688,72 @@ func (ec *executionContext) fieldContext_UpdateAssetPayload_asset(_ context.Cont return fc, nil } +func (ec *executionContext) _UpdateAuditPayload_audit(ctx context.Context, field graphql.CollectedField, obj *types.UpdateAuditPayload) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_UpdateAuditPayload_audit(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Audit, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.Audit) + fc.Result = res + return ec.marshalNAudit2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐAudit(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_UpdateAuditPayload_audit(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "UpdateAuditPayload", + 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_Audit_id(ctx, field) + case "organization": + return ec.fieldContext_Audit_organization(ctx, field) + case "framework": + return ec.fieldContext_Audit_framework(ctx, field) + case "validFrom": + return ec.fieldContext_Audit_validFrom(ctx, field) + case "validUntil": + return ec.fieldContext_Audit_validUntil(ctx, field) + case "report": + return ec.fieldContext_Audit_report(ctx, field) + case "reportUrl": + return ec.fieldContext_Audit_reportUrl(ctx, field) + case "state": + return ec.fieldContext_Audit_state(ctx, field) + case "createdAt": + return ec.fieldContext_Audit_createdAt(ctx, field) + case "updatedAt": + return ec.fieldContext_Audit_updatedAt(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Audit", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _UpdateControlPayload_control(ctx context.Context, field graphql.CollectedField, obj *types.UpdateControlPayload) (ret graphql.Marshaler) { fc, err := ec.fieldContext_UpdateControlPayload_control(ctx, field) if err != nil { @@ -31795,6 +34221,8 @@ func (ec *executionContext) fieldContext_UpdateOrganizationPayload_organization( return ec.fieldContext_Organization_assets(ctx, field) case "data": return ec.fieldContext_Organization_data(ctx, field) + case "audits": + return ec.fieldContext_Organization_audits(ctx, field) case "createdAt": return ec.fieldContext_Organization_createdAt(ctx, field) case "updatedAt": @@ -32120,6 +34548,72 @@ func (ec *executionContext) fieldContext_UpdateVendorPayload_vendor(_ context.Co return fc, nil } +func (ec *executionContext) _UploadAuditReportPayload_audit(ctx context.Context, field graphql.CollectedField, obj *types.UploadAuditReportPayload) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_UploadAuditReportPayload_audit(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Audit, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.Audit) + fc.Result = res + return ec.marshalNAudit2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐAudit(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_UploadAuditReportPayload_audit(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "UploadAuditReportPayload", + 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_Audit_id(ctx, field) + case "organization": + return ec.fieldContext_Audit_organization(ctx, field) + case "framework": + return ec.fieldContext_Audit_framework(ctx, field) + case "validFrom": + return ec.fieldContext_Audit_validFrom(ctx, field) + case "validUntil": + return ec.fieldContext_Audit_validUntil(ctx, field) + case "report": + return ec.fieldContext_Audit_report(ctx, field) + case "reportUrl": + return ec.fieldContext_Audit_reportUrl(ctx, field) + case "state": + return ec.fieldContext_Audit_state(ctx, field) + case "createdAt": + return ec.fieldContext_Audit_createdAt(ctx, field) + case "updatedAt": + return ec.fieldContext_Audit_updatedAt(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Audit", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _UploadMeasureEvidencePayload_evidenceEdge(ctx context.Context, field graphql.CollectedField, obj *types.UploadMeasureEvidencePayload) (ret graphql.Marshaler) { fc, err := ec.fieldContext_UploadMeasureEvidencePayload_evidenceEdge(ctx, field) if err != nil { @@ -33012,6 +35506,8 @@ func (ec *executionContext) fieldContext_Vendor_organization(_ context.Context, return ec.fieldContext_Organization_assets(ctx, field) case "data": return ec.fieldContext_Organization_data(ctx, field) + case "audits": + return ec.fieldContext_Organization_audits(ctx, field) case "createdAt": return ec.fieldContext_Organization_createdAt(ctx, field) case "updatedAt": @@ -37775,6 +40271,40 @@ func (ec *executionContext) unmarshalInputAssignTaskInput(ctx context.Context, o return it, nil } +func (ec *executionContext) unmarshalInputAuditOrder(ctx context.Context, obj any) (types.AuditOrderBy, error) { + var it types.AuditOrderBy + 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.unmarshalNOrderDirection2githubᚗcomᚋgetproboᚋ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.unmarshalNAuditOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditOrderField(ctx, v) + if err != nil { + return it, err + } + it.Field = data + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputBulkPublishDocumentVersionsInput(ctx context.Context, obj any) (types.BulkPublishDocumentVersionsInput, error) { var it types.BulkPublishDocumentVersionsInput asMap := map[string]any{} @@ -38072,6 +40602,61 @@ func (ec *executionContext) unmarshalInputCreateAssetInput(ctx context.Context, return it, nil } +func (ec *executionContext) unmarshalInputCreateAuditInput(ctx context.Context, obj any) (types.CreateAuditInput, error) { + var it types.CreateAuditInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"organizationId", "frameworkId", "validFrom", "validUntil", "state"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "organizationId": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("organizationId")) + data, err := ec.unmarshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v) + if err != nil { + return it, err + } + it.OrganizationID = data + case "frameworkId": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("frameworkId")) + data, err := ec.unmarshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v) + if err != nil { + return it, err + } + it.FrameworkID = data + case "validFrom": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("validFrom")) + data, err := ec.unmarshalODatetime2ᚖtimeᚐTime(ctx, v) + if err != nil { + return it, err + } + it.ValidFrom = data + case "validUntil": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("validUntil")) + data, err := ec.unmarshalODatetime2ᚖtimeᚐTime(ctx, v) + if err != nil { + return it, err + } + it.ValidUntil = data + case "state": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("state")) + data, err := ec.unmarshalOAuditState2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditState(ctx, v) + if err != nil { + return it, err + } + it.State = data + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputCreateControlDocumentMappingInput(ctx context.Context, obj any) (types.CreateControlDocumentMappingInput, error) { var it types.CreateControlDocumentMappingInput asMap := map[string]any{} @@ -39103,6 +41688,60 @@ func (ec *executionContext) unmarshalInputDeleteAssetInput(ctx context.Context, return it, nil } +func (ec *executionContext) unmarshalInputDeleteAuditInput(ctx context.Context, obj any) (types.DeleteAuditInput, error) { + var it types.DeleteAuditInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"auditId"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "auditId": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("auditId")) + data, err := ec.unmarshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v) + if err != nil { + return it, err + } + it.AuditID = data + } + } + + return it, nil +} + +func (ec *executionContext) unmarshalInputDeleteAuditReportInput(ctx context.Context, obj any) (types.DeleteAuditReportInput, error) { + var it types.DeleteAuditReportInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"auditId"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "auditId": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("auditId")) + data, err := ec.unmarshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v) + if err != nil { + return it, err + } + it.AuditID = data + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputDeleteControlDocumentMappingInput(ctx context.Context, obj any) (types.DeleteControlDocumentMappingInput, error) { var it types.DeleteControlDocumentMappingInput asMap := map[string]any{} @@ -40502,6 +43141,54 @@ func (ec *executionContext) unmarshalInputUpdateAssetInput(ctx context.Context, return it, nil } +func (ec *executionContext) unmarshalInputUpdateAuditInput(ctx context.Context, obj any) (types.UpdateAuditInput, error) { + var it types.UpdateAuditInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"id", "validFrom", "validUntil", "state"} + 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.unmarshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v) + if err != nil { + return it, err + } + it.ID = data + case "validFrom": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("validFrom")) + data, err := ec.unmarshalODatetime2ᚖtimeᚐTime(ctx, v) + if err != nil { + return it, err + } + it.ValidFrom = data + case "validUntil": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("validUntil")) + data, err := ec.unmarshalODatetime2ᚖtimeᚐTime(ctx, v) + if err != nil { + return it, err + } + it.ValidUntil = data + case "state": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("state")) + data, err := ec.unmarshalOAuditState2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditState(ctx, v) + if err != nil { + return it, err + } + it.State = data + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputUpdateControlInput(ctx context.Context, obj any) (types.UpdateControlInput, error) { var it types.UpdateControlInput asMap := map[string]any{} @@ -41240,6 +43927,40 @@ func (ec *executionContext) unmarshalInputUpdateVendorInput(ctx context.Context, return it, nil } +func (ec *executionContext) unmarshalInputUploadAuditReportInput(ctx context.Context, obj any) (types.UploadAuditReportInput, error) { + var it types.UploadAuditReportInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"auditId", "file"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "auditId": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("auditId")) + data, err := ec.unmarshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v) + if err != nil { + return it, err + } + it.AuditID = data + case "file": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("file")) + data, err := ec.unmarshalNUpload2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚐUpload(ctx, v) + if err != nil { + return it, err + } + it.File = data + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputUploadMeasureEvidenceInput(ctx context.Context, obj any) (types.UploadMeasureEvidenceInput, error) { var it types.UploadMeasureEvidenceInput asMap := map[string]any{} @@ -41549,6 +44270,13 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj return graphql.Null } return ec._Risk(ctx, sel, obj) + case types.Report: + return ec._Report(ctx, sel, &obj) + case *types.Report: + if obj == nil { + return graphql.Null + } + return ec._Report(ctx, sel, obj) case types.People: return ec._People(ctx, sel, &obj) case *types.People: @@ -41626,6 +44354,13 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj return graphql.Null } return ec._Connector(ctx, sel, obj) + case types.Audit: + return ec._Audit(ctx, sel, &obj) + case *types.Audit: + if obj == nil { + return graphql.Null + } + return ec._Audit(ctx, sel, obj) case types.Asset: return ec._Asset(ctx, sel, &obj) case *types.Asset: @@ -42057,6 +44792,326 @@ func (ec *executionContext) _AssignTaskPayload(ctx context.Context, sel ast.Sele return out } +var auditImplementors = []string{"Audit", "Node"} + +func (ec *executionContext) _Audit(ctx context.Context, sel ast.SelectionSet, obj *types.Audit) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, auditImplementors) + + 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("Audit") + case "id": + out.Values[i] = ec._Audit_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "organization": + 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._Audit_organization(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 "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._Audit_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 "validFrom": + out.Values[i] = ec._Audit_validFrom(ctx, field, obj) + case "validUntil": + out.Values[i] = ec._Audit_validUntil(ctx, field, obj) + case "report": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Audit_report(ctx, field, obj) + 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 "reportUrl": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Audit_reportUrl(ctx, field, obj) + 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 "state": + out.Values[i] = ec._Audit_state(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "createdAt": + out.Values[i] = ec._Audit_createdAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "updatedAt": + out.Values[i] = ec._Audit_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 auditConnectionImplementors = []string{"AuditConnection"} + +func (ec *executionContext) _AuditConnection(ctx context.Context, sel ast.SelectionSet, obj *types.AuditConnection) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, auditConnectionImplementors) + + 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("AuditConnection") + case "totalCount": + 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._AuditConnection_totalCount(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 "edges": + out.Values[i] = ec._AuditConnection_edges(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "pageInfo": + out.Values[i] = ec._AuditConnection_pageInfo(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 auditEdgeImplementors = []string{"AuditEdge"} + +func (ec *executionContext) _AuditEdge(ctx context.Context, sel ast.SelectionSet, obj *types.AuditEdge) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, auditEdgeImplementors) + + 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("AuditEdge") + case "cursor": + out.Values[i] = ec._AuditEdge_cursor(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "node": + out.Values[i] = ec._AuditEdge_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 bulkPublishDocumentVersionsPayloadImplementors = []string{"BulkPublishDocumentVersionsPayload"} func (ec *executionContext) _BulkPublishDocumentVersionsPayload(ctx context.Context, sel ast.SelectionSet, obj *types.BulkPublishDocumentVersionsPayload) graphql.Marshaler { @@ -42707,6 +45762,45 @@ func (ec *executionContext) _CreateAssetPayload(ctx context.Context, sel ast.Sel return out } +var createAuditPayloadImplementors = []string{"CreateAuditPayload"} + +func (ec *executionContext) _CreateAuditPayload(ctx context.Context, sel ast.SelectionSet, obj *types.CreateAuditPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, createAuditPayloadImplementors) + + 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("CreateAuditPayload") + case "auditEdge": + out.Values[i] = ec._CreateAuditPayload_auditEdge(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 createControlDocumentMappingPayloadImplementors = []string{"CreateControlDocumentMappingPayload"} func (ec *executionContext) _CreateControlDocumentMappingPayload(ctx context.Context, sel ast.SelectionSet, obj *types.CreateControlDocumentMappingPayload) graphql.Marshaler { @@ -43725,6 +46819,84 @@ func (ec *executionContext) _DeleteAssetPayload(ctx context.Context, sel ast.Sel return out } +var deleteAuditPayloadImplementors = []string{"DeleteAuditPayload"} + +func (ec *executionContext) _DeleteAuditPayload(ctx context.Context, sel ast.SelectionSet, obj *types.DeleteAuditPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, deleteAuditPayloadImplementors) + + 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("DeleteAuditPayload") + case "deletedAuditId": + out.Values[i] = ec._DeleteAuditPayload_deletedAuditId(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 deleteAuditReportPayloadImplementors = []string{"DeleteAuditReportPayload"} + +func (ec *executionContext) _DeleteAuditReportPayload(ctx context.Context, sel ast.SelectionSet, obj *types.DeleteAuditReportPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, deleteAuditReportPayloadImplementors) + + 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("DeleteAuditReportPayload") + case "audit": + out.Values[i] = ec._DeleteAuditReportPayload_audit(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 deleteControlDocumentMappingPayloadImplementors = []string{"DeleteControlDocumentMappingPayload"} func (ec *executionContext) _DeleteControlDocumentMappingPayload(ctx context.Context, sel ast.SelectionSet, obj *types.DeleteControlDocumentMappingPayload) graphql.Marshaler { @@ -46886,6 +50058,41 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) if out.Values[i] == graphql.Null { out.Invalids++ } + case "createAudit": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_createAudit(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "updateAudit": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_updateAudit(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deleteAudit": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_deleteAudit(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "uploadAuditReport": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_uploadAuditReport(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deleteAuditReport": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_deleteAuditReport(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -47394,6 +50601,42 @@ func (ec *executionContext) _Organization(ctx context.Context, sel ast.Selection continue } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "audits": + 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._Organization_audits(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 "createdAt": out.Values[i] = ec._Organization_createdAt(ctx, field, obj) @@ -47940,6 +51183,108 @@ func (ec *executionContext) _RemoveUserPayload(ctx context.Context, sel ast.Sele return out } +var reportImplementors = []string{"Report", "Node"} + +func (ec *executionContext) _Report(ctx context.Context, sel ast.SelectionSet, obj *types.Report) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, reportImplementors) + + 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("Report") + case "id": + out.Values[i] = ec._Report_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "objectKey": + out.Values[i] = ec._Report_objectKey(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "mimeType": + out.Values[i] = ec._Report_mimeType(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "filename": + out.Values[i] = ec._Report_filename(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "size": + out.Values[i] = ec._Report_size(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "downloadUrl": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Report_downloadUrl(ctx, field, obj) + 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 "createdAt": + out.Values[i] = ec._Report_createdAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "updatedAt": + out.Values[i] = ec._Report_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 requestEvidencePayloadImplementors = []string{"RequestEvidencePayload"} func (ec *executionContext) _RequestEvidencePayload(ctx context.Context, sel ast.SelectionSet, obj *types.RequestEvidencePayload) graphql.Marshaler { @@ -48914,6 +52259,45 @@ func (ec *executionContext) _UpdateAssetPayload(ctx context.Context, sel ast.Sel return out } +var updateAuditPayloadImplementors = []string{"UpdateAuditPayload"} + +func (ec *executionContext) _UpdateAuditPayload(ctx context.Context, sel ast.SelectionSet, obj *types.UpdateAuditPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, updateAuditPayloadImplementors) + + 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("UpdateAuditPayload") + case "audit": + out.Values[i] = ec._UpdateAuditPayload_audit(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 updateControlPayloadImplementors = []string{"UpdateControlPayload"} func (ec *executionContext) _UpdateControlPayload(ctx context.Context, sel ast.SelectionSet, obj *types.UpdateControlPayload) graphql.Marshaler { @@ -49343,6 +52727,45 @@ func (ec *executionContext) _UpdateVendorPayload(ctx context.Context, sel ast.Se return out } +var uploadAuditReportPayloadImplementors = []string{"UploadAuditReportPayload"} + +func (ec *executionContext) _UploadAuditReportPayload(ctx context.Context, sel ast.SelectionSet, obj *types.UploadAuditReportPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, uploadAuditReportPayloadImplementors) + + 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("UploadAuditReportPayload") + case "audit": + out.Values[i] = ec._UploadAuditReportPayload_audit(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 uploadMeasureEvidencePayloadImplementors = []string{"UploadMeasureEvidencePayload"} func (ec *executionContext) _UploadMeasureEvidencePayload(ctx context.Context, sel ast.SelectionSet, obj *types.UploadMeasureEvidencePayload) graphql.Marshaler { @@ -51074,6 +54497,150 @@ func (ec *executionContext) marshalNAssignTaskPayload2ᚖgithubᚗcomᚋgetprobo return ec._AssignTaskPayload(ctx, sel, v) } +func (ec *executionContext) marshalNAudit2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐAudit(ctx context.Context, sel ast.SelectionSet, v *types.Audit) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Audit(ctx, sel, v) +} + +func (ec *executionContext) marshalNAuditConnection2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐAuditConnection(ctx context.Context, sel ast.SelectionSet, v types.AuditConnection) graphql.Marshaler { + return ec._AuditConnection(ctx, sel, &v) +} + +func (ec *executionContext) marshalNAuditConnection2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐAuditConnection(ctx context.Context, sel ast.SelectionSet, v *types.AuditConnection) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._AuditConnection(ctx, sel, v) +} + +func (ec *executionContext) marshalNAuditEdge2ᚕᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐAuditEdgeᚄ(ctx context.Context, sel ast.SelectionSet, v []*types.AuditEdge) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNAuditEdge2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐAuditEdge(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNAuditEdge2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐAuditEdge(ctx context.Context, sel ast.SelectionSet, v *types.AuditEdge) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._AuditEdge(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNAuditOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditOrderField(ctx context.Context, v any) (coredata.AuditOrderField, error) { + tmp, err := graphql.UnmarshalString(v) + res := unmarshalNAuditOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditOrderField[tmp] + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNAuditOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditOrderField(ctx context.Context, sel ast.SelectionSet, v coredata.AuditOrderField) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(marshalNAuditOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditOrderField[v]) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +var ( + unmarshalNAuditOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditOrderField = map[string]coredata.AuditOrderField{ + "CREATED_AT": coredata.AuditOrderFieldCreatedAt, + "VALID_FROM": coredata.AuditOrderFieldValidFrom, + "VALID_UNTIL": coredata.AuditOrderFieldValidUntil, + "STATE": coredata.AuditOrderFieldState, + } + marshalNAuditOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditOrderField = map[coredata.AuditOrderField]string{ + coredata.AuditOrderFieldCreatedAt: "CREATED_AT", + coredata.AuditOrderFieldValidFrom: "VALID_FROM", + coredata.AuditOrderFieldValidUntil: "VALID_UNTIL", + coredata.AuditOrderFieldState: "STATE", + } +) + +func (ec *executionContext) unmarshalNAuditState2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditState(ctx context.Context, v any) (coredata.AuditState, error) { + tmp, err := graphql.UnmarshalString(v) + res := unmarshalNAuditState2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditState[tmp] + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNAuditState2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditState(ctx context.Context, sel ast.SelectionSet, v coredata.AuditState) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(marshalNAuditState2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditState[v]) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +var ( + unmarshalNAuditState2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditState = map[string]coredata.AuditState{ + "NOT_STARTED": coredata.AuditStateNotStarted, + "IN_PROGRESS": coredata.AuditStateInProgress, + "COMPLETED": coredata.AuditStateCompleted, + "REJECTED": coredata.AuditStateRejected, + "OUTDATED": coredata.AuditStateOutdated, + } + marshalNAuditState2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditState = map[coredata.AuditState]string{ + coredata.AuditStateNotStarted: "NOT_STARTED", + coredata.AuditStateInProgress: "IN_PROGRESS", + coredata.AuditStateCompleted: "COMPLETED", + coredata.AuditStateRejected: "REJECTED", + coredata.AuditStateOutdated: "OUTDATED", + } +) + func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context, v any) (bool, error) { res, err := graphql.UnmarshalBoolean(v) return res, graphql.ErrorOnPath(ctx, err) @@ -51457,6 +55024,25 @@ func (ec *executionContext) marshalNCreateAssetPayload2ᚖgithubᚗcomᚋgetprob return ec._CreateAssetPayload(ctx, sel, v) } +func (ec *executionContext) unmarshalNCreateAuditInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateAuditInput(ctx context.Context, v any) (types.CreateAuditInput, error) { + res, err := ec.unmarshalInputCreateAuditInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNCreateAuditPayload2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateAuditPayload(ctx context.Context, sel ast.SelectionSet, v types.CreateAuditPayload) graphql.Marshaler { + return ec._CreateAuditPayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNCreateAuditPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateAuditPayload(ctx context.Context, sel ast.SelectionSet, v *types.CreateAuditPayload) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._CreateAuditPayload(ctx, sel, v) +} + func (ec *executionContext) unmarshalNCreateControlDocumentMappingInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateControlDocumentMappingInput(ctx context.Context, v any) (types.CreateControlDocumentMappingInput, error) { res, err := ec.unmarshalInputCreateControlDocumentMappingInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) @@ -52016,6 +55602,44 @@ func (ec *executionContext) marshalNDeleteAssetPayload2ᚖgithubᚗcomᚋgetprob return ec._DeleteAssetPayload(ctx, sel, v) } +func (ec *executionContext) unmarshalNDeleteAuditInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteAuditInput(ctx context.Context, v any) (types.DeleteAuditInput, error) { + res, err := ec.unmarshalInputDeleteAuditInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNDeleteAuditPayload2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteAuditPayload(ctx context.Context, sel ast.SelectionSet, v types.DeleteAuditPayload) graphql.Marshaler { + return ec._DeleteAuditPayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNDeleteAuditPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteAuditPayload(ctx context.Context, sel ast.SelectionSet, v *types.DeleteAuditPayload) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._DeleteAuditPayload(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNDeleteAuditReportInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteAuditReportInput(ctx context.Context, v any) (types.DeleteAuditReportInput, error) { + res, err := ec.unmarshalInputDeleteAuditReportInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNDeleteAuditReportPayload2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteAuditReportPayload(ctx context.Context, sel ast.SelectionSet, v types.DeleteAuditReportPayload) graphql.Marshaler { + return ec._DeleteAuditReportPayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNDeleteAuditReportPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteAuditReportPayload(ctx context.Context, sel ast.SelectionSet, v *types.DeleteAuditReportPayload) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._DeleteAuditReportPayload(ctx, sel, v) +} + func (ec *executionContext) unmarshalNDeleteControlDocumentMappingInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteControlDocumentMappingInput(ctx context.Context, v any) (types.DeleteControlDocumentMappingInput, error) { res, err := ec.unmarshalInputDeleteControlDocumentMappingInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) @@ -54065,6 +57689,25 @@ func (ec *executionContext) marshalNUpdateAssetPayload2ᚖgithubᚗcomᚋgetprob return ec._UpdateAssetPayload(ctx, sel, v) } +func (ec *executionContext) unmarshalNUpdateAuditInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateAuditInput(ctx context.Context, v any) (types.UpdateAuditInput, error) { + res, err := ec.unmarshalInputUpdateAuditInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNUpdateAuditPayload2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateAuditPayload(ctx context.Context, sel ast.SelectionSet, v types.UpdateAuditPayload) graphql.Marshaler { + return ec._UpdateAuditPayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNUpdateAuditPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateAuditPayload(ctx context.Context, sel ast.SelectionSet, v *types.UpdateAuditPayload) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._UpdateAuditPayload(ctx, sel, v) +} + func (ec *executionContext) unmarshalNUpdateControlInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateControlInput(ctx context.Context, v any) (types.UpdateControlInput, error) { res, err := ec.unmarshalInputUpdateControlInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) @@ -54290,6 +57933,25 @@ func (ec *executionContext) marshalNUpload2githubᚗcomᚋ99designsᚋgqlgenᚋg return res } +func (ec *executionContext) unmarshalNUploadAuditReportInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUploadAuditReportInput(ctx context.Context, v any) (types.UploadAuditReportInput, error) { + res, err := ec.unmarshalInputUploadAuditReportInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNUploadAuditReportPayload2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUploadAuditReportPayload(ctx context.Context, sel ast.SelectionSet, v types.UploadAuditReportPayload) graphql.Marshaler { + return ec._UploadAuditReportPayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNUploadAuditReportPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUploadAuditReportPayload(ctx context.Context, sel ast.SelectionSet, v *types.UploadAuditReportPayload) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._UploadAuditReportPayload(ctx, sel, v) +} + func (ec *executionContext) unmarshalNUploadMeasureEvidenceInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUploadMeasureEvidenceInput(ctx context.Context, v any) (types.UploadMeasureEvidenceInput, error) { res, err := ec.unmarshalInputUploadMeasureEvidenceInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) @@ -55150,6 +58812,50 @@ var ( } ) +func (ec *executionContext) unmarshalOAuditOrder2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐAuditOrderBy(ctx context.Context, v any) (*types.AuditOrderBy, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputAuditOrder(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalOAuditState2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditState(ctx context.Context, v any) (*coredata.AuditState, error) { + if v == nil { + return nil, nil + } + tmp, err := graphql.UnmarshalString(v) + res := unmarshalOAuditState2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditState[tmp] + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOAuditState2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditState(ctx context.Context, sel ast.SelectionSet, v *coredata.AuditState) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalString(marshalOAuditState2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditState[*v]) + return res +} + +var ( + unmarshalOAuditState2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditState = map[string]coredata.AuditState{ + "NOT_STARTED": coredata.AuditStateNotStarted, + "IN_PROGRESS": coredata.AuditStateInProgress, + "COMPLETED": coredata.AuditStateCompleted, + "REJECTED": coredata.AuditStateRejected, + "OUTDATED": coredata.AuditStateOutdated, + } + marshalOAuditState2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐAuditState = map[coredata.AuditState]string{ + coredata.AuditStateNotStarted: "NOT_STARTED", + coredata.AuditStateInProgress: "IN_PROGRESS", + coredata.AuditStateCompleted: "COMPLETED", + coredata.AuditStateRejected: "REJECTED", + coredata.AuditStateOutdated: "OUTDATED", + } +) + func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v any) (bool, error) { res, err := graphql.UnmarshalBoolean(v) return res, graphql.ErrorOnPath(ctx, err) @@ -55664,6 +59370,13 @@ func (ec *executionContext) unmarshalOPeopleOrder2ᚖgithubᚗcomᚋgetproboᚋp return &res, graphql.ErrorOnPath(ctx, err) } +func (ec *executionContext) marshalOReport2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐReport(ctx context.Context, sel ast.SelectionSet, v *types.Report) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Report(ctx, sel, v) +} + func (ec *executionContext) unmarshalORiskFilter2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐRiskFilter(ctx context.Context, v any) (*types.RiskFilter, error) { if v == nil { return nil, nil diff --git a/pkg/server/api/console/v1/types/audit.go b/pkg/server/api/console/v1/types/audit.go new file mode 100644 index 000000000..44591295e --- /dev/null +++ b/pkg/server/api/console/v1/types/audit.go @@ -0,0 +1,71 @@ +// 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 ( + "github.com/getprobo/probo/pkg/coredata" + "github.com/getprobo/probo/pkg/gid" + "github.com/getprobo/probo/pkg/page" +) + +type ( + AuditOrderBy OrderBy[coredata.AuditOrderField] + + AuditConnection struct { + TotalCount int + Edges []*AuditEdge + PageInfo PageInfo + + Resolver any + ParentID gid.GID + } +) + +func NewAuditConnection( + p *page.Page[*coredata.Audit, coredata.AuditOrderField], + parentType any, + parentID gid.GID, +) *AuditConnection { + edges := make([]*AuditEdge, len(p.Data)) + for i, audit := range p.Data { + edges[i] = NewAuditEdge(audit, p.Cursor.OrderBy.Field) + } + + return &AuditConnection{ + Edges: edges, + PageInfo: *NewPageInfo(p), + + Resolver: parentType, + ParentID: parentID, + } +} + +func NewAudit(a *coredata.Audit) *Audit { + return &Audit{ + ID: a.ID, + ValidFrom: a.ValidFrom, + ValidUntil: a.ValidUntil, + State: a.State, + CreatedAt: a.CreatedAt, + UpdatedAt: a.UpdatedAt, + } +} + +func NewAuditEdge(a *coredata.Audit, orderField coredata.AuditOrderField) *AuditEdge { + return &AuditEdge{ + Node: NewAudit(a), + Cursor: a.CursorKey(orderField), + } +} diff --git a/pkg/server/api/console/v1/types/report.go b/pkg/server/api/console/v1/types/report.go new file mode 100644 index 000000000..ebe889f09 --- /dev/null +++ b/pkg/server/api/console/v1/types/report.go @@ -0,0 +1,31 @@ +// 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 ( + "github.com/getprobo/probo/pkg/coredata" +) + +func NewReport(r *coredata.Report) *Report { + return &Report{ + ID: r.ID, + ObjectKey: r.ObjectKey, + MimeType: r.MimeType, + Filename: r.Filename, + Size: int(r.Size), + CreatedAt: r.CreatedAt, + UpdatedAt: r.UpdatedAt, + } +} diff --git a/pkg/server/api/console/v1/types/types.go b/pkg/server/api/console/v1/types/types.go index d0f1df697..82be470ba 100644 --- a/pkg/server/api/console/v1/types/types.go +++ b/pkg/server/api/console/v1/types/types.go @@ -56,6 +56,27 @@ type AssignTaskPayload struct { Task *Task `json:"task"` } +type Audit struct { + ID gid.GID `json:"id"` + Organization *Organization `json:"organization"` + Framework *Framework `json:"framework"` + ValidFrom *time.Time `json:"validFrom,omitempty"` + ValidUntil *time.Time `json:"validUntil,omitempty"` + Report *Report `json:"report,omitempty"` + ReportURL *string `json:"reportUrl,omitempty"` + State coredata.AuditState `json:"state"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` +} + +func (Audit) IsNode() {} +func (this Audit) GetID() gid.GID { return this.ID } + +type AuditEdge struct { + Cursor page.CursorKey `json:"cursor"` + Node *Audit `json:"node"` +} + type BulkPublishDocumentVersionsInput struct { DocumentIds []gid.GID `json:"documentIds"` Changelog string `json:"changelog"` @@ -158,6 +179,18 @@ type CreateAssetPayload struct { AssetEdge *AssetEdge `json:"assetEdge"` } +type CreateAuditInput struct { + OrganizationID gid.GID `json:"organizationId"` + FrameworkID gid.GID `json:"frameworkId"` + ValidFrom *time.Time `json:"validFrom,omitempty"` + ValidUntil *time.Time `json:"validUntil,omitempty"` + State *coredata.AuditState `json:"state,omitempty"` +} + +type CreateAuditPayload struct { + AuditEdge *AuditEdge `json:"auditEdge"` +} + type CreateControlDocumentMappingInput struct { ControlID gid.GID `json:"controlId"` DocumentID gid.GID `json:"documentId"` @@ -399,6 +432,22 @@ type DeleteAssetPayload struct { DeletedAssetID gid.GID `json:"deletedAssetId"` } +type DeleteAuditInput struct { + AuditID gid.GID `json:"auditId"` +} + +type DeleteAuditPayload struct { + DeletedAuditID gid.GID `json:"deletedAuditId"` +} + +type DeleteAuditReportInput struct { + AuditID gid.GID `json:"auditId"` +} + +type DeleteAuditReportPayload struct { + Audit *Audit `json:"audit"` +} + type DeleteControlDocumentMappingInput struct { ControlID gid.GID `json:"controlId"` DocumentID gid.GID `json:"documentId"` @@ -766,6 +815,7 @@ type Organization struct { Tasks *TaskConnection `json:"tasks"` Assets *AssetConnection `json:"assets"` Data *DatumConnection `json:"data"` + Audits *AuditConnection `json:"audits"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` } @@ -838,6 +888,20 @@ type RemoveUserPayload struct { Success bool `json:"success"` } +type Report struct { + ID gid.GID `json:"id"` + ObjectKey string `json:"objectKey"` + MimeType string `json:"mimeType"` + Filename string `json:"filename"` + Size int `json:"size"` + DownloadURL *string `json:"downloadUrl,omitempty"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` +} + +func (Report) IsNode() {} +func (this Report) GetID() gid.GID { return this.ID } + type RequestEvidenceInput struct { TaskID gid.GID `json:"taskId"` Name string `json:"name"` @@ -951,6 +1015,17 @@ type UpdateAssetPayload struct { Asset *Asset `json:"asset"` } +type UpdateAuditInput struct { + ID gid.GID `json:"id"` + ValidFrom *time.Time `json:"validFrom,omitempty"` + ValidUntil *time.Time `json:"validUntil,omitempty"` + State *coredata.AuditState `json:"state,omitempty"` +} + +type UpdateAuditPayload struct { + Audit *Audit `json:"audit"` +} + type UpdateControlInput struct { ID gid.GID `json:"id"` SectionTitle *string `json:"sectionTitle,omitempty"` @@ -1102,6 +1177,15 @@ type UpdateVendorPayload struct { Vendor *Vendor `json:"vendor"` } +type UploadAuditReportInput struct { + AuditID gid.GID `json:"auditId"` + File graphql.Upload `json:"file"` +} + +type UploadAuditReportPayload struct { + Audit *Audit `json:"audit"` +} + type UploadMeasureEvidenceInput struct { MeasureID gid.GID `json:"measureId"` File graphql.Upload `json:"file"` diff --git a/pkg/server/api/console/v1/v1_resolver.go b/pkg/server/api/console/v1/v1_resolver.go index 2c76fc59b..ee3fb0d9e 100644 --- a/pkg/server/api/console/v1/v1_resolver.go +++ b/pkg/server/api/console/v1/v1_resolver.go @@ -107,6 +107,88 @@ func (r *assetConnectionResolver) TotalCount(ctx context.Context, obj *types.Ass panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } +// Organization is the resolver for the organization field. +func (r *auditResolver) Organization(ctx context.Context, obj *types.Audit) (*types.Organization, error) { + prb := r.ProboService(ctx, obj.ID.TenantID()) + + audit, err := prb.Audits.Get(ctx, obj.ID) + if err != nil { + return nil, fmt.Errorf("cannot load audit: %w", err) + } + + organization, err := prb.Organizations.Get(ctx, audit.OrganizationID) + if err != nil { + return nil, fmt.Errorf("cannot load organization: %w", err) + } + + return types.NewOrganization(organization), nil +} + +// Framework is the resolver for the framework field. +func (r *auditResolver) Framework(ctx context.Context, obj *types.Audit) (*types.Framework, error) { + prb := r.ProboService(ctx, obj.ID.TenantID()) + + audit, err := prb.Audits.Get(ctx, obj.ID) + if err != nil { + return nil, fmt.Errorf("cannot load audit: %w", err) + } + + framework, err := prb.Frameworks.Get(ctx, audit.FrameworkID) + if err != nil { + return nil, fmt.Errorf("cannot load framework: %w", err) + } + + return types.NewFramework(framework), nil +} + +// Report is the resolver for the report field. +func (r *auditResolver) Report(ctx context.Context, obj *types.Audit) (*types.Report, error) { + prb := r.ProboService(ctx, obj.ID.TenantID()) + + audit, err := prb.Audits.Get(ctx, obj.ID) + if err != nil { + return nil, fmt.Errorf("cannot load audit: %w", err) + } + + if audit.ReportID == nil { + return nil, nil + } + + report, err := prb.Reports.Get(ctx, *audit.ReportID) + if err != nil { + return nil, fmt.Errorf("cannot load report: %w", err) + } + + return types.NewReport(report), nil +} + +// ReportURL is the resolver for the reportUrl field. +func (r *auditResolver) ReportURL(ctx context.Context, obj *types.Audit) (*string, error) { + prb := r.ProboService(ctx, obj.ID.TenantID()) + + if obj.Report == nil { + return nil, nil + } + + url, err := prb.Audits.GenerateReportURL(ctx, obj.ID, 15*time.Minute) + if err != nil { + return nil, fmt.Errorf("cannot generate report URL: %w", err) + } + + return url, nil +} + +// TotalCount is the resolver for the totalCount field. +func (r *auditConnectionResolver) TotalCount(ctx context.Context, obj *types.AuditConnection) (int, error) { + prb := r.ProboService(ctx, obj.ParentID.TenantID()) + + count, err := prb.Audits.CountForOrganizationID(ctx, obj.ParentID) + if err != nil { + return 0, fmt.Errorf("cannot count audits: %w", err) + } + return count, nil +} + // Framework is the resolver for the framework field. func (r *controlResolver) Framework(ctx context.Context, obj *types.Control) (*types.Framework, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -2191,6 +2273,101 @@ func (r *mutationResolver) DeleteDatum(ctx context.Context, input types.DeleteDa }, nil } +// CreateAudit is the resolver for the createAudit field. +func (r *mutationResolver) CreateAudit(ctx context.Context, input types.CreateAuditInput) (*types.CreateAuditPayload, error) { + prb := r.ProboService(ctx, input.OrganizationID.TenantID()) + + req := probo.CreateAuditRequest{ + OrganizationID: input.OrganizationID, + FrameworkID: input.FrameworkID, + ValidFrom: input.ValidFrom, + ValidUntil: input.ValidUntil, + State: input.State, + } + + audit, err := prb.Audits.Create(ctx, &req) + if err != nil { + panic(fmt.Errorf("cannot create audit: %w", err)) + } + + return &types.CreateAuditPayload{ + AuditEdge: types.NewAuditEdge(audit, coredata.AuditOrderFieldCreatedAt), + }, nil +} + +// UpdateAudit is the resolver for the updateAudit field. +func (r *mutationResolver) UpdateAudit(ctx context.Context, input types.UpdateAuditInput) (*types.UpdateAuditPayload, error) { + prb := r.ProboService(ctx, input.ID.TenantID()) + + req := probo.UpdateAuditRequest{ + ID: input.ID, + ValidFrom: input.ValidFrom, + ValidUntil: input.ValidUntil, + State: input.State, + } + + audit, err := prb.Audits.Update(ctx, &req) + if err != nil { + panic(fmt.Errorf("cannot update audit: %w", err)) + } + + return &types.UpdateAuditPayload{ + Audit: types.NewAudit(audit), + }, nil +} + +// DeleteAudit is the resolver for the deleteAudit field. +func (r *mutationResolver) DeleteAudit(ctx context.Context, input types.DeleteAuditInput) (*types.DeleteAuditPayload, error) { + prb := r.ProboService(ctx, input.AuditID.TenantID()) + + err := prb.Audits.Delete(ctx, input.AuditID) + if err != nil { + panic(fmt.Errorf("cannot delete audit: %w", err)) + } + + return &types.DeleteAuditPayload{ + DeletedAuditID: input.AuditID, + }, nil +} + +// UploadAuditReport is the resolver for the uploadAuditReport field. +func (r *mutationResolver) UploadAuditReport(ctx context.Context, input types.UploadAuditReportInput) (*types.UploadAuditReportPayload, error) { + prb := r.ProboService(ctx, input.AuditID.TenantID()) + + req := probo.UploadAuditReportRequest{ + AuditID: input.AuditID, + File: probo.File{ + Content: input.File.File, + Filename: input.File.Filename, + Size: input.File.Size, + ContentType: input.File.ContentType, + }, + } + + audit, err := prb.Audits.UploadReport(ctx, req) + if err != nil { + panic(fmt.Errorf("cannot upload audit report: %w", err)) + } + + return &types.UploadAuditReportPayload{ + Audit: types.NewAudit(audit), + }, nil +} + +// DeleteAuditReport is the resolver for the deleteAuditReport field. +func (r *mutationResolver) DeleteAuditReport(ctx context.Context, input types.DeleteAuditReportInput) (*types.DeleteAuditReportPayload, error) { + prb := r.ProboService(ctx, input.AuditID.TenantID()) + + audit, err := prb.Audits.DeleteReport(ctx, input.AuditID) + if err != nil { + return nil, fmt.Errorf("cannot delete audit report: %w", err) + } + + return &types.DeleteAuditReportPayload{ + Audit: types.NewAudit(audit), + }, nil +} + // LogoURL is the resolver for the logoUrl field. func (r *organizationResolver) LogoURL(ctx context.Context, obj *types.Organization) (*string, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -2516,6 +2693,31 @@ func (r *organizationResolver) Data(ctx context.Context, obj *types.Organization return types.NewDataConnection(page, r, obj.ID), nil } +// Audits is the resolver for the audits field. +func (r *organizationResolver) Audits(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AuditOrderBy) (*types.AuditConnection, error) { + prb := r.ProboService(ctx, obj.ID.TenantID()) + + pageOrderBy := page.OrderBy[coredata.AuditOrderField]{ + Field: coredata.AuditOrderFieldCreatedAt, + Direction: page.OrderDirectionDesc, + } + if orderBy != nil { + pageOrderBy = page.OrderBy[coredata.AuditOrderField]{ + Field: orderBy.Field, + Direction: orderBy.Direction, + } + } + + cursor := types.NewCursor(first, after, last, before, pageOrderBy) + + page, err := prb.Audits.ListForOrganizationID(ctx, obj.ID, cursor) + if err != nil { + panic(fmt.Errorf("cannot list organization audits: %w", err)) + } + + return types.NewAuditConnection(page, r, obj.ID), nil +} + // TotalCount is the resolver for the totalCount field. func (r *peopleConnectionResolver) TotalCount(ctx context.Context, obj *types.PeopleConnection) (int, error) { prb := r.ProboService(ctx, obj.ParentID.TenantID()) @@ -2635,6 +2837,18 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error panic(fmt.Errorf("cannot get data: %w", err)) } return types.NewDatum(datum), nil + case coredata.AuditEntityType: + audit, err := prb.Audits.Get(ctx, id) + if err != nil { + panic(fmt.Errorf("cannot get audit: %w", err)) + } + return types.NewAudit(audit), nil + case coredata.ReportEntityType: + report, err := prb.Reports.Get(ctx, id) + if err != nil { + panic(fmt.Errorf("cannot get report: %w", err)) + } + return types.NewReport(report), nil default: } @@ -2652,6 +2866,18 @@ func (r *queryResolver) Viewer(ctx context.Context) (*types.Viewer, error) { }, nil } +// DownloadURL is the resolver for the downloadUrl field. +func (r *reportResolver) DownloadURL(ctx context.Context, obj *types.Report) (*string, error) { + prb := r.ProboService(ctx, obj.ID.TenantID()) + + url, err := prb.Reports.GenerateDownloadURL(ctx, obj.ID, 15*time.Minute) + if err != nil { + return nil, fmt.Errorf("cannot generate download URL: %w", err) + } + + return url, nil +} + // Owner is the resolver for the owner field. func (r *riskResolver) Owner(ctx context.Context, obj *types.Risk) (*types.People, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -3136,6 +3362,14 @@ func (r *Resolver) AssetConnection() schema.AssetConnectionResolver { return &assetConnectionResolver{r} } +// Audit returns schema.AuditResolver implementation. +func (r *Resolver) Audit() schema.AuditResolver { return &auditResolver{r} } + +// AuditConnection returns schema.AuditConnectionResolver implementation. +func (r *Resolver) AuditConnection() schema.AuditConnectionResolver { + return &auditConnectionResolver{r} +} + // Control returns schema.ControlResolver implementation. func (r *Resolver) Control() schema.ControlResolver { return &controlResolver{r} } @@ -3208,6 +3442,9 @@ func (r *Resolver) PeopleConnection() schema.PeopleConnectionResolver { // Query returns schema.QueryResolver implementation. func (r *Resolver) Query() schema.QueryResolver { return &queryResolver{r} } +// Report returns schema.ReportResolver implementation. +func (r *Resolver) Report() schema.ReportResolver { return &reportResolver{r} } + // Risk returns schema.RiskResolver implementation. func (r *Resolver) Risk() schema.RiskResolver { return &riskResolver{r} } @@ -3246,6 +3483,8 @@ func (r *Resolver) Viewer() schema.ViewerResolver { return &viewerResolver{r} } type assetResolver struct{ *Resolver } type assetConnectionResolver struct{ *Resolver } +type auditResolver struct{ *Resolver } +type auditConnectionResolver struct{ *Resolver } type controlResolver struct{ *Resolver } type controlConnectionResolver struct{ *Resolver } type datumResolver struct{ *Resolver } @@ -3264,6 +3503,7 @@ type mutationResolver struct{ *Resolver } type organizationResolver struct{ *Resolver } type peopleConnectionResolver struct{ *Resolver } type queryResolver struct{ *Resolver } +type reportResolver struct{ *Resolver } type riskResolver struct{ *Resolver } type riskConnectionResolver struct{ *Resolver } type taskResolver struct{ *Resolver }