Check snapshot type and id from url

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2025-08-28 17:57:12 +02:00
parent 7d80a7d5f4
commit da4553beb2
16 changed files with 227 additions and 45 deletions

View File

@@ -32,7 +32,7 @@ export function PageError({ resetErrorBoundary, error: propsError }: Props) {
} }
}, [location, resetErrorBoundary]); }, [location, resetErrorBoundary]);
if (!error) { if (!error || (error && error.toString().includes("PAGE_NOT_FOUND"))) {
return ( return (
<div className={classNames.wrapper}> <div className={classNames.wrapper}>
<h1 className={classNames.title}> <h1 className={classNames.title}>

View File

@@ -1,7 +1,9 @@
import { IconClock } from "@probo/ui"; import { IconClock } from "@probo/ui";
import { useTranslate } from "@probo/i18n"; import { useTranslate } from "@probo/i18n";
import { useLazyLoadQuery, graphql } from "react-relay"; import { useLazyLoadQuery, graphql } from "react-relay";
import { useLocation } from "react-router";
import type { SnapshotBannerQuery } from "./__generated__/SnapshotBannerQuery.graphql"; import type { SnapshotBannerQuery } from "./__generated__/SnapshotBannerQuery.graphql";
import { getSnapshotTypeUrlPath } from "@probo/helpers";
const snapshotQuery = graphql` const snapshotQuery = graphql`
query SnapshotBannerQuery($snapshotId: ID!) { query SnapshotBannerQuery($snapshotId: ID!) {
@@ -9,18 +11,25 @@ const snapshotQuery = graphql`
... on Snapshot { ... on Snapshot {
id id
name name
type
createdAt createdAt
} }
} }
} }
`; `;
const isSnapshotTypeValidForUrl = (type: string, pathname: string) => {
const urlPath = getSnapshotTypeUrlPath(type);
return pathname.includes(urlPath);
};
type Props = { type Props = {
snapshotId: string; snapshotId: string;
}; };
export function SnapshotBanner({ snapshotId }: Props) { export function SnapshotBanner({ snapshotId }: Props) {
const { __, dateFormat } = useTranslate(); const { __, dateFormat } = useTranslate();
const location = useLocation();
const data = useLazyLoadQuery<SnapshotBannerQuery>(snapshotQuery, { snapshotId }); const data = useLazyLoadQuery<SnapshotBannerQuery>(snapshotQuery, { snapshotId });
const snapshot = data.node; const snapshot = data.node;
@@ -29,6 +38,10 @@ export function SnapshotBanner({ snapshotId }: Props) {
return null; return null;
} }
if (snapshot.type && !isSnapshotTypeValidForUrl(snapshot.type, location.pathname)) {
throw new Error("PAGE_NOT_FOUND");
}
return ( return (
<div className="bg-warning rounded-lg p-4 flex items-center gap-3"> <div className="bg-warning rounded-lg p-4 flex items-center gap-3">
<IconClock className="text-warning-600 flex-shrink-0" size={20} /> <IconClock className="text-warning-600 flex-shrink-0" size={20} />

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<a11c48ca33ac17dd7eaf6eeca4a0c20d>> * @generated SignedSource<<3c8b528580116deec511c979e209cfc3>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -9,6 +9,7 @@
// @ts-nocheck // @ts-nocheck
import { ConcreteRequest } from 'relay-runtime'; import { ConcreteRequest } from 'relay-runtime';
export type SnapshotsType = "ASSETS" | "COMPLIANCE_REGISTRIES" | "DATA" | "NONCONFORMITY_REGISTRIES" | "RISKS" | "VENDORS";
export type SnapshotBannerQuery$variables = { export type SnapshotBannerQuery$variables = {
snapshotId: string; snapshotId: string;
}; };
@@ -17,6 +18,7 @@ export type SnapshotBannerQuery$data = {
readonly createdAt?: any; readonly createdAt?: any;
readonly id?: string; readonly id?: string;
readonly name?: string; readonly name?: string;
readonly type?: SnapshotsType;
}; };
}; };
export type SnapshotBannerQuery = { export type SnapshotBannerQuery = {
@@ -54,6 +56,13 @@ v3 = {
"storageKey": null "storageKey": null
}, },
v4 = { v4 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "type",
"storageKey": null
},
v5 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
@@ -80,7 +89,8 @@ return {
"selections": [ "selections": [
(v2/*: any*/), (v2/*: any*/),
(v3/*: any*/), (v3/*: any*/),
(v4/*: any*/) (v4/*: any*/),
(v5/*: any*/)
], ],
"type": "Snapshot", "type": "Snapshot",
"abstractKey": null "abstractKey": null
@@ -118,7 +128,8 @@ return {
"kind": "InlineFragment", "kind": "InlineFragment",
"selections": [ "selections": [
(v3/*: any*/), (v3/*: any*/),
(v4/*: any*/) (v4/*: any*/),
(v5/*: any*/)
], ],
"type": "Snapshot", "type": "Snapshot",
"abstractKey": null "abstractKey": null
@@ -129,16 +140,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "8f21371ececf96444bb6b00e52783573", "cacheID": "7e026c7c030cd116b4794260934c394f",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "SnapshotBannerQuery", "name": "SnapshotBannerQuery",
"operationKind": "query", "operationKind": "query",
"text": "query SnapshotBannerQuery(\n $snapshotId: ID!\n) {\n node(id: $snapshotId) {\n __typename\n ... on Snapshot {\n id\n name\n createdAt\n }\n id\n }\n}\n" "text": "query SnapshotBannerQuery(\n $snapshotId: ID!\n) {\n node(id: $snapshotId) {\n __typename\n ... on Snapshot {\n id\n name\n type\n createdAt\n }\n id\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "1602d5b6c0ae4a3122998e4d3419af05"; (node as any).hash = "e50a4bb5133d8e918b8b2b9d2a42f1d1";
export default node; export default node;

View File

@@ -19,6 +19,7 @@ export const datumNodeQuery = graphql`
node(id: $dataId) { node(id: $dataId) {
... on Datum { ... on Datum {
id id
snapshotId
name name
dataClassification dataClassification
owner { owner {

View File

@@ -22,6 +22,7 @@ export const nonconformityRegistryNodeQuery = graphql`
node(id: $nonconformityRegistryId) { node(id: $nonconformityRegistryId) {
... on NonconformityRegistry { ... on NonconformityRegistry {
id id
snapshotId
referenceId referenceId
description description
dateIdentified dateIdentified

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<ff7246a675948a19ab124dbf6095b3bb>> * @generated SignedSource<<5cfbdbc980894977800a18064306f2c1>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -27,6 +27,7 @@ export type DatumGraphNodeQuery$data = {
readonly fullName: string; readonly fullName: string;
readonly id: string; readonly id: string;
}; };
readonly snapshotId?: string | null | undefined;
readonly updatedAt?: any; readonly updatedAt?: any;
readonly vendors?: { readonly vendors?: {
readonly edges: ReadonlyArray<{ readonly edges: ReadonlyArray<{
@@ -71,17 +72,24 @@ v3 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "name", "name": "snapshotId",
"storageKey": null "storageKey": null
}, },
v4 = { v4 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "dataClassification", "name": "name",
"storageKey": null "storageKey": null
}, },
v5 = { v5 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "dataClassification",
"storageKey": null
},
v6 = {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "People", "concreteType": "People",
@@ -100,7 +108,7 @@ v5 = {
], ],
"storageKey": null "storageKey": null
}, },
v6 = { v7 = {
"alias": null, "alias": null,
"args": [ "args": [
{ {
@@ -131,7 +139,7 @@ v6 = {
"plural": false, "plural": false,
"selections": [ "selections": [
(v2/*: any*/), (v2/*: any*/),
(v3/*: any*/), (v4/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -155,7 +163,7 @@ v6 = {
], ],
"storageKey": "vendors(first:50)" "storageKey": "vendors(first:50)"
}, },
v7 = { v8 = {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "Organization", "concreteType": "Organization",
@@ -167,14 +175,14 @@ v7 = {
], ],
"storageKey": null "storageKey": null
}, },
v8 = { v9 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "createdAt", "name": "createdAt",
"storageKey": null "storageKey": null
}, },
v9 = { v10 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
@@ -206,7 +214,8 @@ return {
(v6/*: any*/), (v6/*: any*/),
(v7/*: any*/), (v7/*: any*/),
(v8/*: any*/), (v8/*: any*/),
(v9/*: any*/) (v9/*: any*/),
(v10/*: any*/)
], ],
"type": "Datum", "type": "Datum",
"abstractKey": null "abstractKey": null
@@ -249,7 +258,8 @@ return {
(v6/*: any*/), (v6/*: any*/),
(v7/*: any*/), (v7/*: any*/),
(v8/*: any*/), (v8/*: any*/),
(v9/*: any*/) (v9/*: any*/),
(v10/*: any*/)
], ],
"type": "Datum", "type": "Datum",
"abstractKey": null "abstractKey": null
@@ -260,16 +270,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "7dcd0ba0b57e917592a333f2368f65c4", "cacheID": "6ed49a3413c0214dc95da9a422e484b4",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "DatumGraphNodeQuery", "name": "DatumGraphNodeQuery",
"operationKind": "query", "operationKind": "query",
"text": "query DatumGraphNodeQuery(\n $dataId: ID!\n) {\n node(id: $dataId) {\n __typename\n ... on Datum {\n id\n name\n dataClassification\n owner {\n id\n fullName\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n category\n }\n }\n }\n organization {\n id\n }\n createdAt\n updatedAt\n }\n id\n }\n}\n" "text": "query DatumGraphNodeQuery(\n $dataId: ID!\n) {\n node(id: $dataId) {\n __typename\n ... on Datum {\n id\n snapshotId\n name\n dataClassification\n owner {\n id\n fullName\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n category\n }\n }\n }\n organization {\n id\n }\n createdAt\n updatedAt\n }\n id\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "c8a8fc6a37cce32b83f53379317d8f67"; (node as any).hash = "2f4df20b67f8b21eda5f510f250abda1";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<7b7982ce6c305e82103ca4422bbb7c2f>> * @generated SignedSource<<4ea62d99e8a73491f8125cb3e8d8e4b5>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -39,6 +39,7 @@ export type NonconformityRegistryGraphNodeQuery$data = {
}; };
readonly referenceId?: string; readonly referenceId?: string;
readonly rootCause?: string; readonly rootCause?: string;
readonly snapshotId?: string | null | undefined;
readonly status?: NonconformityRegistryStatus; readonly status?: NonconformityRegistryStatus;
readonly updatedAt?: any; readonly updatedAt?: any;
}; };
@@ -74,59 +75,66 @@ v3 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "referenceId", "name": "snapshotId",
"storageKey": null "storageKey": null
}, },
v4 = { v4 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "description", "name": "referenceId",
"storageKey": null "storageKey": null
}, },
v5 = { v5 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "dateIdentified", "name": "description",
"storageKey": null "storageKey": null
}, },
v6 = { v6 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "rootCause", "name": "dateIdentified",
"storageKey": null "storageKey": null
}, },
v7 = { v7 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "correctiveAction", "name": "rootCause",
"storageKey": null "storageKey": null
}, },
v8 = { v8 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "dueDate", "name": "correctiveAction",
"storageKey": null "storageKey": null
}, },
v9 = { v9 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "status", "name": "dueDate",
"storageKey": null "storageKey": null
}, },
v10 = { v10 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "status",
"storageKey": null
},
v11 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "effectivenessCheck", "name": "effectivenessCheck",
"storageKey": null "storageKey": null
}, },
v11 = [ v12 = [
(v2/*: any*/), (v2/*: any*/),
{ {
"alias": null, "alias": null,
@@ -136,7 +144,7 @@ v11 = [
"storageKey": null "storageKey": null
} }
], ],
v12 = { v13 = {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "Audit", "concreteType": "Audit",
@@ -152,13 +160,13 @@ v12 = {
"kind": "LinkedField", "kind": "LinkedField",
"name": "framework", "name": "framework",
"plural": false, "plural": false,
"selections": (v11/*: any*/), "selections": (v12/*: any*/),
"storageKey": null "storageKey": null
} }
], ],
"storageKey": null "storageKey": null
}, },
v13 = { v14 = {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "People", "concreteType": "People",
@@ -177,24 +185,24 @@ v13 = {
], ],
"storageKey": null "storageKey": null
}, },
v14 = { v15 = {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "Organization", "concreteType": "Organization",
"kind": "LinkedField", "kind": "LinkedField",
"name": "organization", "name": "organization",
"plural": false, "plural": false,
"selections": (v11/*: any*/), "selections": (v12/*: any*/),
"storageKey": null "storageKey": null
}, },
v15 = { v16 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "createdAt", "name": "createdAt",
"storageKey": null "storageKey": null
}, },
v16 = { v17 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
@@ -228,11 +236,12 @@ return {
(v8/*: any*/), (v8/*: any*/),
(v9/*: any*/), (v9/*: any*/),
(v10/*: any*/), (v10/*: any*/),
(v12/*: any*/), (v11/*: any*/),
(v13/*: any*/), (v13/*: any*/),
(v14/*: any*/), (v14/*: any*/),
(v15/*: any*/), (v15/*: any*/),
(v16/*: any*/) (v16/*: any*/),
(v17/*: any*/)
], ],
"type": "NonconformityRegistry", "type": "NonconformityRegistry",
"abstractKey": null "abstractKey": null
@@ -277,11 +286,12 @@ return {
(v8/*: any*/), (v8/*: any*/),
(v9/*: any*/), (v9/*: any*/),
(v10/*: any*/), (v10/*: any*/),
(v12/*: any*/), (v11/*: any*/),
(v13/*: any*/), (v13/*: any*/),
(v14/*: any*/), (v14/*: any*/),
(v15/*: any*/), (v15/*: any*/),
(v16/*: any*/) (v16/*: any*/),
(v17/*: any*/)
], ],
"type": "NonconformityRegistry", "type": "NonconformityRegistry",
"abstractKey": null "abstractKey": null
@@ -292,16 +302,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "fd9bf2453d001f33ed1e32ad5784b647", "cacheID": "ab9100da91dff02cc103e6cf3f04b9e2",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "NonconformityRegistryGraphNodeQuery", "name": "NonconformityRegistryGraphNodeQuery",
"operationKind": "query", "operationKind": "query",
"text": "query NonconformityRegistryGraphNodeQuery(\n $nonconformityRegistryId: ID!\n) {\n node(id: $nonconformityRegistryId) {\n __typename\n ... on NonconformityRegistry {\n id\n referenceId\n description\n dateIdentified\n rootCause\n correctiveAction\n dueDate\n status\n effectivenessCheck\n audit {\n id\n framework {\n id\n name\n }\n }\n owner {\n id\n fullName\n }\n organization {\n id\n name\n }\n createdAt\n updatedAt\n }\n id\n }\n}\n" "text": "query NonconformityRegistryGraphNodeQuery(\n $nonconformityRegistryId: ID!\n) {\n node(id: $nonconformityRegistryId) {\n __typename\n ... on NonconformityRegistry {\n id\n snapshotId\n referenceId\n description\n dateIdentified\n rootCause\n correctiveAction\n dueDate\n status\n effectivenessCheck\n audit {\n id\n framework {\n id\n name\n }\n }\n owner {\n id\n fullName\n }\n organization {\n id\n name\n }\n createdAt\n updatedAt\n }\n id\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "3395719bf2203fba19ccc94d6f740014"; (node as any).hash = "207465c315f95b9b26e7687c4ef17cbf";
export default node; export default node;

View File

@@ -27,6 +27,7 @@ import { VendorsMultiSelectField } from "/components/form/VendorsMultiSelectFiel
import { useFormWithSchema } from "/hooks/useFormWithSchema"; import { useFormWithSchema } from "/hooks/useFormWithSchema";
import z from "zod"; import z from "zod";
import { SnapshotBanner } from "/components/SnapshotBanner"; import { SnapshotBanner } from "/components/SnapshotBanner";
import { validateSnapshotConsistency } from "@probo/helpers";
import type { DatumGraphNodeQuery } from "/hooks/graph/__generated__/DatumGraphNodeQuery.graphql"; import type { DatumGraphNodeQuery } from "/hooks/graph/__generated__/DatumGraphNodeQuery.graphql";
const updateDatumSchema = z.object({ const updateDatumSchema = z.object({
@@ -51,6 +52,8 @@ export default function DatumDetailsPage(props: Props) {
const datumEntry = queryData.node; const datumEntry = queryData.node;
validateSnapshotConsistency(datumEntry, snapshotId);
const { __ } = useTranslate(); const { __ } = useTranslate();
const organizationId = useOrganizationId(); const organizationId = useOrganizationId();

View File

@@ -32,7 +32,7 @@ import { PeopleSelectField } from "/components/form/PeopleSelectField";
import { AuditSelectField } from "/components/form/AuditSelectField"; import { AuditSelectField } from "/components/form/AuditSelectField";
import { useFormWithSchema } from "/hooks/useFormWithSchema"; import { useFormWithSchema } from "/hooks/useFormWithSchema";
import z from "zod"; import z from "zod";
import { getStatusVariant, getStatusLabel, formatDatetime, getNonconformityRegistryStatusOptions } from "@probo/helpers"; import { getStatusVariant, getStatusLabel, formatDatetime, getNonconformityRegistryStatusOptions, validateSnapshotConsistency } from "@probo/helpers";
import type { NonconformityRegistryGraphNodeQuery } from "/hooks/graph/__generated__/NonconformityRegistryGraphNodeQuery.graphql"; import type { NonconformityRegistryGraphNodeQuery } from "/hooks/graph/__generated__/NonconformityRegistryGraphNodeQuery.graphql";
const updateRegistrySchema = z.object({ const updateRegistrySchema = z.object({
@@ -63,6 +63,8 @@ export default function NonconformityRegistryDetailsPage(props: Props) {
const { snapshotId } = useParams<{ snapshotId?: string }>(); const { snapshotId } = useParams<{ snapshotId?: string }>();
const isSnapshotMode = Boolean(snapshotId); const isSnapshotMode = Boolean(snapshotId);
validateSnapshotConsistency(registry, snapshotId);
const deleteRegistry = useDeleteNonconformityRegistry( const deleteRegistry = useDeleteNonconformityRegistry(
{ id: registry.id!, referenceId: registry.referenceId! }, { id: registry.id!, referenceId: registry.referenceId! },
ConnectionHandler.getConnectionID( ConnectionHandler.getConnectionID(

View File

@@ -15,7 +15,7 @@ export { certificationCategoryLabel, certifications } from "./certifications";
export { availableFrameworks } from "./frameworks"; export { availableFrameworks } from "./frameworks";
export { getDocumentTypeLabel, documentTypes } from "./documents"; export { getDocumentTypeLabel, documentTypes } from "./documents";
export { getAssetTypeVariant, getCriticityVariant } from "./assets"; export { getAssetTypeVariant, getCriticityVariant } from "./assets";
export { getSnapshotTypeLabel, getSnapshotTypeUrlPath, snapshotTypes } from "./snapshots"; export { getSnapshotTypeLabel, getSnapshotTypeUrlPath, snapshotTypes, validateSnapshotConsistency } from "./snapshots";
export { getAuditStateLabel, getAuditStateVariant, auditStates } from "./audits"; export { getAuditStateLabel, getAuditStateVariant, auditStates } from "./audits";
export { getStatusVariant, getStatusLabel, getNonconformityRegistryStatusOptions, getComplianceRegistryStatusOptions, registryStatuses } from "./registryStatus"; export { getStatusVariant, getStatusLabel, getNonconformityRegistryStatusOptions, getComplianceRegistryStatusOptions, registryStatuses } from "./registryStatus";
export { promisifyMutation } from "./relay"; export { promisifyMutation } from "./relay";

View File

@@ -38,3 +38,16 @@ export function getSnapshotTypeUrlPath(type?: string): string {
return ""; return "";
} }
} }
export interface SnapshotableResource {
snapshotId?: string | null | undefined;
}
export function validateSnapshotConsistency(
resource: SnapshotableResource | null | undefined,
urlSnapshotId?: string | null | undefined
): void {
if (resource && resource.snapshotId !== (urlSnapshotId ?? null)) {
throw new Error("PAGE_NOT_FOUND");
}
}

View File

@@ -1703,6 +1703,7 @@ type Audit implements Node {
type NonconformityRegistry implements Node { type NonconformityRegistry implements Node {
id: ID! id: ID!
snapshotId: ID
organization: Organization! @goField(forceResolver: true) organization: Organization! @goField(forceResolver: true)
referenceId: String! referenceId: String!
description: String description: String
@@ -3689,6 +3690,7 @@ type DeleteAssetPayload {
type Datum implements Node { type Datum implements Node {
id: ID! id: ID!
snapshotId: ID
name: String! name: String!
dataClassification: DataClassification! dataClassification: DataClassification!
owner: People! @goField(forceResolver: true) owner: People! @goField(forceResolver: true)

View File

@@ -403,6 +403,7 @@ type ComplexityRoot struct {
Name func(childComplexity int) int Name func(childComplexity int) int
Organization func(childComplexity int) int Organization func(childComplexity int) int
Owner func(childComplexity int) int Owner func(childComplexity int) int
SnapshotID func(childComplexity int) int
UpdatedAt func(childComplexity int) int UpdatedAt func(childComplexity int) int
Vendors func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy) int Vendors func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy) int
} }
@@ -851,6 +852,7 @@ type ComplexityRoot struct {
Owner func(childComplexity int) int Owner func(childComplexity int) int
ReferenceID func(childComplexity int) int ReferenceID func(childComplexity int) int
RootCause func(childComplexity int) int RootCause func(childComplexity int) int
SnapshotID func(childComplexity int) int
Status func(childComplexity int) int Status func(childComplexity int) int
UpdatedAt func(childComplexity int) int UpdatedAt func(childComplexity int) int
} }
@@ -2831,6 +2833,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
return e.complexity.Datum.Owner(childComplexity), true return e.complexity.Datum.Owner(childComplexity), true
case "Datum.snapshotId":
if e.complexity.Datum.SnapshotID == nil {
break
}
return e.complexity.Datum.SnapshotID(childComplexity), true
case "Datum.updatedAt": case "Datum.updatedAt":
if e.complexity.Datum.UpdatedAt == nil { if e.complexity.Datum.UpdatedAt == nil {
break break
@@ -5271,6 +5280,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
return e.complexity.NonconformityRegistry.RootCause(childComplexity), true return e.complexity.NonconformityRegistry.RootCause(childComplexity), true
case "NonconformityRegistry.snapshotId":
if e.complexity.NonconformityRegistry.SnapshotID == nil {
break
}
return e.complexity.NonconformityRegistry.SnapshotID(childComplexity), true
case "NonconformityRegistry.status": case "NonconformityRegistry.status":
if e.complexity.NonconformityRegistry.Status == nil { if e.complexity.NonconformityRegistry.Status == nil {
break break
@@ -9579,6 +9595,7 @@ type Audit implements Node {
type NonconformityRegistry implements Node { type NonconformityRegistry implements Node {
id: ID! id: ID!
snapshotId: ID
organization: Organization! @goField(forceResolver: true) organization: Organization! @goField(forceResolver: true)
referenceId: String! referenceId: String!
description: String description: String
@@ -11565,6 +11582,7 @@ type DeleteAssetPayload {
type Datum implements Node { type Datum implements Node {
id: ID! id: ID!
snapshotId: ID
name: String! name: String!
dataClassification: DataClassification! dataClassification: DataClassification!
owner: People! @goField(forceResolver: true) owner: People! @goField(forceResolver: true)
@@ -26001,6 +26019,47 @@ func (ec *executionContext) fieldContext_Datum_id(_ context.Context, field graph
return fc, nil return fc, nil
} }
func (ec *executionContext) _Datum_snapshotId(ctx context.Context, field graphql.CollectedField, obj *types.Datum) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Datum_snapshotId(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.SnapshotID, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*gid.GID)
fc.Result = res
return ec.marshalOID2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Datum_snapshotId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Datum",
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) _Datum_name(ctx context.Context, field graphql.CollectedField, obj *types.Datum) (ret graphql.Marshaler) { func (ec *executionContext) _Datum_name(ctx context.Context, field graphql.CollectedField, obj *types.Datum) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Datum_name(ctx, field) fc, err := ec.fieldContext_Datum_name(ctx, field)
if err != nil { if err != nil {
@@ -26633,6 +26692,8 @@ func (ec *executionContext) fieldContext_DatumEdge_node(_ context.Context, field
switch field.Name { switch field.Name {
case "id": case "id":
return ec.fieldContext_Datum_id(ctx, field) return ec.fieldContext_Datum_id(ctx, field)
case "snapshotId":
return ec.fieldContext_Datum_snapshotId(ctx, field)
case "name": case "name":
return ec.fieldContext_Datum_name(ctx, field) return ec.fieldContext_Datum_name(ctx, field)
case "dataClassification": case "dataClassification":
@@ -39897,6 +39958,47 @@ func (ec *executionContext) fieldContext_NonconformityRegistry_id(_ context.Cont
return fc, nil return fc, nil
} }
func (ec *executionContext) _NonconformityRegistry_snapshotId(ctx context.Context, field graphql.CollectedField, obj *types.NonconformityRegistry) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_NonconformityRegistry_snapshotId(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.SnapshotID, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*gid.GID)
fc.Result = res
return ec.marshalOID2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_NonconformityRegistry_snapshotId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "NonconformityRegistry",
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) _NonconformityRegistry_organization(ctx context.Context, field graphql.CollectedField, obj *types.NonconformityRegistry) (ret graphql.Marshaler) { func (ec *executionContext) _NonconformityRegistry_organization(ctx context.Context, field graphql.CollectedField, obj *types.NonconformityRegistry) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_NonconformityRegistry_organization(ctx, field) fc, err := ec.fieldContext_NonconformityRegistry_organization(ctx, field)
if err != nil { if err != nil {
@@ -40787,6 +40889,8 @@ func (ec *executionContext) fieldContext_NonconformityRegistryEdge_node(_ contex
switch field.Name { switch field.Name {
case "id": case "id":
return ec.fieldContext_NonconformityRegistry_id(ctx, field) return ec.fieldContext_NonconformityRegistry_id(ctx, field)
case "snapshotId":
return ec.fieldContext_NonconformityRegistry_snapshotId(ctx, field)
case "organization": case "organization":
return ec.fieldContext_NonconformityRegistry_organization(ctx, field) return ec.fieldContext_NonconformityRegistry_organization(ctx, field)
case "referenceId": case "referenceId":
@@ -49740,6 +49844,8 @@ func (ec *executionContext) fieldContext_UpdateDatumPayload_datum(_ context.Cont
switch field.Name { switch field.Name {
case "id": case "id":
return ec.fieldContext_Datum_id(ctx, field) return ec.fieldContext_Datum_id(ctx, field)
case "snapshotId":
return ec.fieldContext_Datum_snapshotId(ctx, field)
case "name": case "name":
return ec.fieldContext_Datum_name(ctx, field) return ec.fieldContext_Datum_name(ctx, field)
case "dataClassification": case "dataClassification":
@@ -50072,6 +50178,8 @@ func (ec *executionContext) fieldContext_UpdateNonconformityRegistryPayload_nonc
switch field.Name { switch field.Name {
case "id": case "id":
return ec.fieldContext_NonconformityRegistry_id(ctx, field) return ec.fieldContext_NonconformityRegistry_id(ctx, field)
case "snapshotId":
return ec.fieldContext_NonconformityRegistry_snapshotId(ctx, field)
case "organization": case "organization":
return ec.fieldContext_NonconformityRegistry_organization(ctx, field) return ec.fieldContext_NonconformityRegistry_organization(ctx, field)
case "referenceId": case "referenceId":
@@ -68827,6 +68935,8 @@ func (ec *executionContext) _Datum(ctx context.Context, sel ast.SelectionSet, ob
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
atomic.AddUint32(&out.Invalids, 1) atomic.AddUint32(&out.Invalids, 1)
} }
case "snapshotId":
out.Values[i] = ec._Datum_snapshotId(ctx, field, obj)
case "name": case "name":
out.Values[i] = ec._Datum_name(ctx, field, obj) out.Values[i] = ec._Datum_name(ctx, field, obj)
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
@@ -73267,6 +73377,8 @@ func (ec *executionContext) _NonconformityRegistry(ctx context.Context, sel ast.
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
atomic.AddUint32(&out.Invalids, 1) atomic.AddUint32(&out.Invalids, 1)
} }
case "snapshotId":
out.Values[i] = ec._NonconformityRegistry_snapshotId(ctx, field, obj)
case "organization": case "organization":
field := field field := field

View File

@@ -56,6 +56,7 @@ func NewDatum(d *coredata.Datum) *Datum {
return &Datum{ return &Datum{
ID: d.ID, ID: d.ID,
Name: d.Name, Name: d.Name,
SnapshotID: d.SnapshotID,
DataClassification: d.DataClassification, DataClassification: d.DataClassification,
CreatedAt: d.CreatedAt, CreatedAt: d.CreatedAt,
UpdatedAt: d.UpdatedAt, UpdatedAt: d.UpdatedAt,

View File

@@ -59,6 +59,7 @@ func NewNonconformityRegistry(nr *coredata.NonconformityRegistry) *Nonconformity
return &NonconformityRegistry{ return &NonconformityRegistry{
ID: nr.ID, ID: nr.ID,
ReferenceID: nr.ReferenceID, ReferenceID: nr.ReferenceID,
SnapshotID: nr.SnapshotID,
Description: nr.Description, Description: nr.Description,
DateIdentified: nr.DateIdentified, DateIdentified: nr.DateIdentified,
RootCause: nr.RootCause, RootCause: nr.RootCause,

View File

@@ -600,6 +600,7 @@ type CreateVendorServicePayload struct {
type Datum struct { type Datum struct {
ID gid.GID `json:"id"` ID gid.GID `json:"id"`
SnapshotID *gid.GID `json:"snapshotId,omitempty"`
Name string `json:"name"` Name string `json:"name"`
DataClassification coredata.DataClassification `json:"dataClassification"` DataClassification coredata.DataClassification `json:"dataClassification"`
Owner *People `json:"owner"` Owner *People `json:"owner"`
@@ -1115,6 +1116,7 @@ type Mutation struct {
type NonconformityRegistry struct { type NonconformityRegistry struct {
ID gid.GID `json:"id"` ID gid.GID `json:"id"`
SnapshotID *gid.GID `json:"snapshotId,omitempty"`
Organization *Organization `json:"organization"` Organization *Organization `json:"organization"`
ReferenceID string `json:"referenceId"` ReferenceID string `json:"referenceId"`
Description *string `json:"description,omitempty"` Description *string `json:"description,omitempty"`