Allow publishing generated documents as minor versions
Generated documents (asset list, risk register, SoA, ...) previously
only ever produced a new major version. Every regeneration of an
auto-built register consumed a major number, even when the change was
trivial. They now accept a minor flag and publish as
currentMajor.currentMinor+1 when set, bypassing the approval flow.
To carry the flag through cleanly, the document publish API was
refactored. The three split mutations (publishMajor, publishMinor,
requestDocumentVersionApproval) and the two bulk variants collapse
into a single publishDocument / bulkPublishDocuments, both taking the
new minor: Boolean! and a now-required changelog: String!. The same
shape flows through the CLI ("prb document publish --minor"), the MCP
tool, the n8n operations, and the Relay dialogs, where each
generated-doc dialog gains a "Publish as minor" button. Publishing
minor without an existing major is rejected with
ErrCannotPublishMinorWithoutMajor.
This is a deliberate breaking change for callers of the prior
mutations.
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
@@ -25,7 +25,7 @@ import {
|
|||||||
useToast,
|
useToast,
|
||||||
} from "@probo/ui";
|
} from "@probo/ui";
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import { useMemo } from "react";
|
import { useMemo, useRef } from "react";
|
||||||
import { useMutation } from "react-relay";
|
import { useMutation } from "react-relay";
|
||||||
import { graphql } from "relay-runtime";
|
import { graphql } from "relay-runtime";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
@@ -83,6 +83,8 @@ export function PublishAssetListDialog({
|
|||||||
const [publish, isPublishing]
|
const [publish, isPublishing]
|
||||||
= useMutation<PublishAssetListDialogMutation>(publishMutation);
|
= useMutation<PublishAssetListDialogMutation>(publishMutation);
|
||||||
|
|
||||||
|
const minorRef = useRef(false);
|
||||||
|
|
||||||
const approverIds = watch("approverIds");
|
const approverIds = watch("approverIds");
|
||||||
const hasApprovers = approverIds.length > 0;
|
const hasApprovers = approverIds.length > 0;
|
||||||
|
|
||||||
@@ -90,8 +92,9 @@ export function PublishAssetListDialog({
|
|||||||
publish({
|
publish({
|
||||||
variables: {
|
variables: {
|
||||||
input: {
|
input: {
|
||||||
|
minor: minorRef.current,
|
||||||
organizationId,
|
organizationId,
|
||||||
approverIds: data.approverIds.length > 0 ? data.approverIds : undefined,
|
approverIds: !minorRef.current && data.approverIds.length > 0 ? data.approverIds : undefined,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
onCompleted(response) {
|
onCompleted(response) {
|
||||||
@@ -145,9 +148,19 @@ export function PublishAssetListDialog({
|
|||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
variant="secondary"
|
||||||
|
icon={IconUpload}
|
||||||
|
onClick={() => { minorRef.current = true; }}
|
||||||
|
disabled={isPublishing}
|
||||||
|
>
|
||||||
|
{__("Publish as minor")}
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
icon={hasApprovers ? IconSend : IconUpload}
|
icon={hasApprovers ? IconSend : IconUpload}
|
||||||
|
onClick={() => { minorRef.current = false; }}
|
||||||
disabled={isPublishing}
|
disabled={isPublishing}
|
||||||
>
|
>
|
||||||
{hasApprovers ? __("Request approval") : __("Publish")}
|
{hasApprovers ? __("Request approval") : __("Publish")}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import {
|
|||||||
useToast,
|
useToast,
|
||||||
} from "@probo/ui";
|
} from "@probo/ui";
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import { useMemo } from "react";
|
import { useMemo, useRef } from "react";
|
||||||
import { useMutation } from "react-relay";
|
import { useMutation } from "react-relay";
|
||||||
import { graphql } from "relay-runtime";
|
import { graphql } from "relay-runtime";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
@@ -83,6 +83,8 @@ export function PublishDataListDialog({
|
|||||||
const [publish, isPublishing]
|
const [publish, isPublishing]
|
||||||
= useMutation<PublishDataListDialogMutation>(publishMutation);
|
= useMutation<PublishDataListDialogMutation>(publishMutation);
|
||||||
|
|
||||||
|
const minorRef = useRef(false);
|
||||||
|
|
||||||
const approverIds = watch("approverIds");
|
const approverIds = watch("approverIds");
|
||||||
const hasApprovers = approverIds.length > 0;
|
const hasApprovers = approverIds.length > 0;
|
||||||
|
|
||||||
@@ -90,8 +92,9 @@ export function PublishDataListDialog({
|
|||||||
publish({
|
publish({
|
||||||
variables: {
|
variables: {
|
||||||
input: {
|
input: {
|
||||||
|
minor: minorRef.current,
|
||||||
organizationId,
|
organizationId,
|
||||||
approverIds: data.approverIds.length > 0 ? data.approverIds : undefined,
|
approverIds: !minorRef.current && data.approverIds.length > 0 ? data.approverIds : undefined,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
onCompleted(response) {
|
onCompleted(response) {
|
||||||
@@ -145,9 +148,19 @@ export function PublishDataListDialog({
|
|||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
variant="secondary"
|
||||||
|
icon={IconUpload}
|
||||||
|
onClick={() => { minorRef.current = true; }}
|
||||||
|
disabled={isPublishing}
|
||||||
|
>
|
||||||
|
{__("Publish as minor")}
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
icon={hasApprovers ? IconSend : IconUpload}
|
icon={hasApprovers ? IconSend : IconUpload}
|
||||||
|
onClick={() => { minorRef.current = false; }}
|
||||||
disabled={isPublishing}
|
disabled={isPublishing}
|
||||||
>
|
>
|
||||||
{hasApprovers ? __("Request approval") : __("Publish")}
|
{hasApprovers ? __("Request approval") : __("Publish")}
|
||||||
|
|||||||
@@ -31,9 +31,7 @@ import { graphql } from "relay-runtime";
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import type { PublishDialog_documentFragment$key } from "#/__generated__/core/PublishDialog_documentFragment.graphql";
|
import type { PublishDialog_documentFragment$key } from "#/__generated__/core/PublishDialog_documentFragment.graphql";
|
||||||
import type { PublishDialog_publishMajorMutation } from "#/__generated__/core/PublishDialog_publishMajorMutation.graphql";
|
import type { PublishDialog_publishMutation } from "#/__generated__/core/PublishDialog_publishMutation.graphql";
|
||||||
import type { PublishDialog_publishMinorMutation } from "#/__generated__/core/PublishDialog_publishMinorMutation.graphql";
|
|
||||||
import type { PublishDialog_requestApprovalMutation } from "#/__generated__/core/PublishDialog_requestApprovalMutation.graphql";
|
|
||||||
import { PeopleMultiSelectField } from "#/components/form/PeopleMultiSelectField";
|
import { PeopleMultiSelectField } from "#/components/form/PeopleMultiSelectField";
|
||||||
import { useFormWithSchema } from "#/hooks/useFormWithSchema";
|
import { useFormWithSchema } from "#/hooks/useFormWithSchema";
|
||||||
import { useOrganizationId } from "#/hooks/useOrganizationId";
|
import { useOrganizationId } from "#/hooks/useOrganizationId";
|
||||||
@@ -57,9 +55,9 @@ const documentFragment = graphql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const publishMajorMutation = graphql`
|
const publishMutation = graphql`
|
||||||
mutation PublishDialog_publishMajorMutation($input: PublishMajorDocumentVersionInput!) {
|
mutation PublishDialog_publishMutation($input: PublishDocumentInput!) {
|
||||||
publishMajorDocumentVersion(input: $input) {
|
publishDocument(input: $input) {
|
||||||
document {
|
document {
|
||||||
id
|
id
|
||||||
status
|
status
|
||||||
@@ -68,30 +66,6 @@ const publishMajorMutation = graphql`
|
|||||||
id
|
id
|
||||||
status
|
status
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const publishMinorMutation = graphql`
|
|
||||||
mutation PublishDialog_publishMinorMutation($input: PublishMinorDocumentVersionInput!) {
|
|
||||||
publishMinorDocumentVersion(input: $input) {
|
|
||||||
document {
|
|
||||||
id
|
|
||||||
status
|
|
||||||
}
|
|
||||||
documentVersion {
|
|
||||||
id
|
|
||||||
status
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const requestApprovalMutation = graphql`
|
|
||||||
mutation PublishDialog_requestApprovalMutation(
|
|
||||||
$input: RequestDocumentVersionApprovalInput!
|
|
||||||
) {
|
|
||||||
requestDocumentVersionApproval(input: $input) {
|
|
||||||
approvalQuorum {
|
approvalQuorum {
|
||||||
id
|
id
|
||||||
status
|
status
|
||||||
@@ -166,62 +140,20 @@ export function PublishDialog({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const [publishMajor, isPublishingMajor]
|
const [publish, isPublishing]
|
||||||
= useMutation<PublishDialog_publishMajorMutation>(publishMajorMutation);
|
= useMutation<PublishDialog_publishMutation>(publishMutation);
|
||||||
const [publishMinor, isPublishingMinor]
|
|
||||||
= useMutation<PublishDialog_publishMinorMutation>(publishMinorMutation);
|
|
||||||
const [requestApproval, isRequesting]
|
|
||||||
= useMutation<PublishDialog_requestApprovalMutation>(requestApprovalMutation);
|
|
||||||
|
|
||||||
const isBusy = isPublishingMajor || isPublishingMinor || isRequesting;
|
|
||||||
const approverIds = watch("approverIds");
|
const approverIds = watch("approverIds");
|
||||||
const hasApprovers = approverIds.length > 0;
|
const hasApprovers = approverIds.length > 0;
|
||||||
const actionRef = useRef<"publish" | "publish-minor" | "request-approval">("publish");
|
const minorRef = useRef(false);
|
||||||
|
|
||||||
const onPublishCompleted = (_: unknown, errors: ReadonlyArray<{ message: string }> | null) => {
|
const submit = (data: z.infer<typeof publishSchema>, minor: boolean) => {
|
||||||
if (errors?.length) {
|
publish({
|
||||||
toast({
|
|
||||||
title: __("Error"),
|
|
||||||
description: formatError(__("Failed to publish document"), [...errors]),
|
|
||||||
variant: "error",
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
toast({
|
|
||||||
title: __("Success"),
|
|
||||||
description: __("Document published successfully."),
|
|
||||||
variant: "success",
|
|
||||||
});
|
|
||||||
dialogRef.current?.close();
|
|
||||||
onSuccess();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onPublishError = (error: Error) => {
|
|
||||||
toast({ title: __("Error"), description: error.message, variant: "error" });
|
|
||||||
};
|
|
||||||
|
|
||||||
const handlePublishMajor = (data: z.infer<typeof publishSchema>) => {
|
|
||||||
publishMajor({
|
|
||||||
variables: { input: { documentId, changelog: data.changelog } },
|
|
||||||
onCompleted: onPublishCompleted,
|
|
||||||
onError: onPublishError,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handlePublishMinor = (data: z.infer<typeof publishSchema>) => {
|
|
||||||
publishMinor({
|
|
||||||
variables: { input: { documentId, changelog: data.changelog } },
|
|
||||||
onCompleted: onPublishCompleted,
|
|
||||||
onError: onPublishError,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const onRequestApproval = (data: z.infer<typeof publishSchema>) => {
|
|
||||||
requestApproval({
|
|
||||||
variables: {
|
variables: {
|
||||||
input: {
|
input: {
|
||||||
documentId,
|
documentId,
|
||||||
approverIds: data.approverIds,
|
minor,
|
||||||
|
approverIds: minor ? [] : data.approverIds,
|
||||||
changelog: data.changelog,
|
changelog: data.changelog,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -229,19 +161,21 @@ export function PublishDialog({
|
|||||||
if (errors?.length) {
|
if (errors?.length) {
|
||||||
toast({
|
toast({
|
||||||
title: __("Error"),
|
title: __("Error"),
|
||||||
description: formatError(__("Failed to request approval"), errors),
|
description: formatError(__("Failed to publish document"), errors),
|
||||||
variant: "error",
|
variant: "error",
|
||||||
});
|
});
|
||||||
} else {
|
return;
|
||||||
toast({
|
|
||||||
title: __("Success"),
|
|
||||||
description: __("Approval requested successfully."),
|
|
||||||
variant: "success",
|
|
||||||
});
|
|
||||||
dialogRef.current?.close();
|
|
||||||
reset();
|
|
||||||
onSuccess();
|
|
||||||
}
|
}
|
||||||
|
toast({
|
||||||
|
title: __("Success"),
|
||||||
|
description: !minor && data.approverIds.length > 0
|
||||||
|
? __("Approval requested successfully.")
|
||||||
|
: __("Document published successfully."),
|
||||||
|
variant: "success",
|
||||||
|
});
|
||||||
|
dialogRef.current?.close();
|
||||||
|
reset();
|
||||||
|
onSuccess();
|
||||||
},
|
},
|
||||||
onError(error) {
|
onError(error) {
|
||||||
toast({ title: __("Error"), description: error.message, variant: "error" });
|
toast({ title: __("Error"), description: error.message, variant: "error" });
|
||||||
@@ -253,17 +187,9 @@ export function PublishDialog({
|
|||||||
<Dialog className="max-w-xl" ref={dialogRef} title={__("Publish document")}>
|
<Dialog className="max-w-xl" ref={dialogRef} title={__("Publish document")}>
|
||||||
<form
|
<form
|
||||||
onSubmit={e => void handleSubmit((data) => {
|
onSubmit={e => void handleSubmit((data) => {
|
||||||
const action = actionRef.current;
|
const minor = minorRef.current;
|
||||||
actionRef.current = "publish";
|
minorRef.current = false;
|
||||||
if (action === "publish-minor") {
|
submit(data, minor);
|
||||||
handlePublishMinor(data);
|
|
||||||
} else if (action === "request-approval") {
|
|
||||||
onRequestApproval(data);
|
|
||||||
} else if (data.approverIds.length > 0) {
|
|
||||||
onRequestApproval(data);
|
|
||||||
} else {
|
|
||||||
handlePublishMajor(data);
|
|
||||||
}
|
|
||||||
})(e)}
|
})(e)}
|
||||||
>
|
>
|
||||||
<DialogContent padded>
|
<DialogContent padded>
|
||||||
@@ -299,49 +225,23 @@ export function PublishDialog({
|
|||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
{hasApprovers
|
<Button
|
||||||
? (
|
type="submit"
|
||||||
<>
|
variant="secondary"
|
||||||
<Button
|
icon={IconUpload}
|
||||||
type="submit"
|
onClick={() => { minorRef.current = true; }}
|
||||||
variant="secondary"
|
disabled={isPublishing}
|
||||||
icon={IconUpload}
|
>
|
||||||
onClick={() => { actionRef.current = "publish-minor"; }}
|
{__("Publish as minor")}
|
||||||
disabled={isBusy}
|
</Button>
|
||||||
>
|
<Button
|
||||||
{__("Publish as minor")}
|
type="submit"
|
||||||
</Button>
|
icon={hasApprovers ? IconSend : IconUpload}
|
||||||
<Button
|
onClick={() => { minorRef.current = false; }}
|
||||||
type="submit"
|
disabled={isPublishing}
|
||||||
icon={IconSend}
|
>
|
||||||
onClick={() => { actionRef.current = "request-approval"; }}
|
{hasApprovers ? __("Request approval") : __("Publish as major")}
|
||||||
disabled={isBusy}
|
</Button>
|
||||||
>
|
|
||||||
{__("Request approval")}
|
|
||||||
</Button>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
: (
|
|
||||||
<>
|
|
||||||
<Button
|
|
||||||
type="submit"
|
|
||||||
variant="secondary"
|
|
||||||
icon={IconUpload}
|
|
||||||
onClick={() => { actionRef.current = "publish-minor"; }}
|
|
||||||
disabled={isBusy}
|
|
||||||
>
|
|
||||||
{__("Publish as minor")}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
type="submit"
|
|
||||||
icon={IconUpload}
|
|
||||||
onClick={() => { actionRef.current = "publish"; }}
|
|
||||||
disabled={isBusy}
|
|
||||||
>
|
|
||||||
{__("Publish as major")}
|
|
||||||
</Button>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</form>
|
</form>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|||||||
@@ -30,8 +30,7 @@ import { useMutation } from "react-relay";
|
|||||||
import { graphql } from "relay-runtime";
|
import { graphql } from "relay-runtime";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import type { PublishDocumentsDialog_majorMutation } from "#/__generated__/core/PublishDocumentsDialog_majorMutation.graphql";
|
import type { PublishDocumentsDialog_bulkPublishMutation } from "#/__generated__/core/PublishDocumentsDialog_bulkPublishMutation.graphql";
|
||||||
import type { PublishDocumentsDialog_minorMutation } from "#/__generated__/core/PublishDocumentsDialog_minorMutation.graphql";
|
|
||||||
import { useFormWithSchema } from "#/hooks/useFormWithSchema";
|
import { useFormWithSchema } from "#/hooks/useFormWithSchema";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -40,27 +39,11 @@ type Props = {
|
|||||||
onSave: () => void;
|
onSave: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const publishMajorMutation = graphql`
|
const bulkPublishMutation = graphql`
|
||||||
mutation PublishDocumentsDialog_majorMutation(
|
mutation PublishDocumentsDialog_bulkPublishMutation(
|
||||||
$input: BulkPublishDocumentVersionsInput!
|
$input: BulkPublishDocumentsInput!
|
||||||
) {
|
) {
|
||||||
bulkPublishMajorDocumentVersions(input: $input) {
|
bulkPublishDocuments(input: $input) {
|
||||||
documentVersions {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
documents {
|
|
||||||
id
|
|
||||||
...DocumentListItemFragment
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const publishMinorMutation = graphql`
|
|
||||||
mutation PublishDocumentsDialog_minorMutation(
|
|
||||||
$input: BulkPublishDocumentVersionsInput!
|
|
||||||
) {
|
|
||||||
bulkPublishMinorDocumentVersions(input: $input) {
|
|
||||||
documentVersions {
|
documentVersions {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
@@ -80,18 +63,14 @@ export function PublishDocumentsDialog({
|
|||||||
const { __ } = useTranslate();
|
const { __ } = useTranslate();
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const dialogRef = useDialogRef();
|
const dialogRef = useDialogRef();
|
||||||
const actionRef = useRef<"major" | "minor">("major");
|
const minorRef = useRef(false);
|
||||||
|
|
||||||
const schema = z.object({
|
const schema = z.object({
|
||||||
changelog: z.string().min(1, __("Changelog is required")),
|
changelog: z.string().min(1, __("Changelog is required")),
|
||||||
});
|
});
|
||||||
|
|
||||||
const [publishMajor, isPublishingMajor]
|
const [publish, isPublishing]
|
||||||
= useMutation<PublishDocumentsDialog_majorMutation>(publishMajorMutation);
|
= useMutation<PublishDocumentsDialog_bulkPublishMutation>(bulkPublishMutation);
|
||||||
const [publishMinor, isPublishingMinor]
|
|
||||||
= useMutation<PublishDocumentsDialog_minorMutation>(publishMinorMutation);
|
|
||||||
|
|
||||||
const isBusy = isPublishingMajor || isPublishingMinor;
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@@ -103,45 +82,42 @@ export function PublishDocumentsDialog({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const onCompleted = (_: unknown, errors: ReadonlyArray<{ message: string }> | null) => {
|
|
||||||
if (errors?.length) {
|
|
||||||
toast({
|
|
||||||
title: __("Error"),
|
|
||||||
description: formatError(__("Failed to publish documents"), [...errors]),
|
|
||||||
variant: "error",
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
toast({
|
|
||||||
title: __("Success"),
|
|
||||||
description: sprintf(__("%s documents published"), documentIds.length),
|
|
||||||
variant: "success",
|
|
||||||
});
|
|
||||||
dialogRef.current?.close();
|
|
||||||
onSave();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onError = (error: Error) => {
|
|
||||||
toast({
|
|
||||||
title: __("Error"),
|
|
||||||
description: error.message,
|
|
||||||
variant: "error",
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSubmit = (data: z.infer<typeof schema>) => {
|
const onSubmit = (data: z.infer<typeof schema>) => {
|
||||||
const variables = {
|
const minor = minorRef.current;
|
||||||
input: {
|
minorRef.current = false;
|
||||||
documentIds,
|
publish({
|
||||||
changelog: data.changelog,
|
variables: {
|
||||||
|
input: {
|
||||||
|
documentIds,
|
||||||
|
minor,
|
||||||
|
changelog: data.changelog,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
onCompleted(_, errors) {
|
||||||
|
if (errors?.length) {
|
||||||
if (actionRef.current === "minor") {
|
toast({
|
||||||
publishMinor({ variables, onCompleted, onError });
|
title: __("Error"),
|
||||||
} else {
|
description: formatError(__("Failed to publish documents"), [...errors]),
|
||||||
publishMajor({ variables, onCompleted, onError });
|
variant: "error",
|
||||||
}
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
toast({
|
||||||
|
title: __("Success"),
|
||||||
|
description: sprintf(__("%s documents published"), documentIds.length),
|
||||||
|
variant: "success",
|
||||||
|
});
|
||||||
|
dialogRef.current?.close();
|
||||||
|
onSave();
|
||||||
|
},
|
||||||
|
onError(error) {
|
||||||
|
toast({
|
||||||
|
title: __("Error"),
|
||||||
|
description: error.message,
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -184,15 +160,15 @@ export function PublishDocumentsDialog({
|
|||||||
type="submit"
|
type="submit"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
icon={IconUpload}
|
icon={IconUpload}
|
||||||
disabled={isBusy}
|
disabled={isPublishing}
|
||||||
onClick={() => { actionRef.current = "minor"; }}
|
onClick={() => { minorRef.current = true; }}
|
||||||
>
|
>
|
||||||
{__("Publish as minor")}
|
{__("Publish as minor")}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={isBusy}
|
disabled={isPublishing}
|
||||||
onClick={() => { actionRef.current = "major"; }}
|
onClick={() => { minorRef.current = false; }}
|
||||||
>
|
>
|
||||||
{sprintf(__("Publish %s documents"), documentIds.length)}
|
{sprintf(__("Publish %s documents"), documentIds.length)}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import {
|
|||||||
useToast,
|
useToast,
|
||||||
} from "@probo/ui";
|
} from "@probo/ui";
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import { useMemo } from "react";
|
import { useMemo, useRef } from "react";
|
||||||
import { useMutation } from "react-relay";
|
import { useMutation } from "react-relay";
|
||||||
import { graphql } from "relay-runtime";
|
import { graphql } from "relay-runtime";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
@@ -83,6 +83,8 @@ export function PublishFindingListDialog({
|
|||||||
const [publish, isPublishing]
|
const [publish, isPublishing]
|
||||||
= useMutation<PublishFindingListDialogMutation>(publishMutation);
|
= useMutation<PublishFindingListDialogMutation>(publishMutation);
|
||||||
|
|
||||||
|
const minorRef = useRef(false);
|
||||||
|
|
||||||
const approverIds = watch("approverIds");
|
const approverIds = watch("approverIds");
|
||||||
const hasApprovers = approverIds.length > 0;
|
const hasApprovers = approverIds.length > 0;
|
||||||
|
|
||||||
@@ -90,8 +92,9 @@ export function PublishFindingListDialog({
|
|||||||
publish({
|
publish({
|
||||||
variables: {
|
variables: {
|
||||||
input: {
|
input: {
|
||||||
|
minor: minorRef.current,
|
||||||
organizationId,
|
organizationId,
|
||||||
approverIds: data.approverIds.length > 0 ? data.approverIds : undefined,
|
approverIds: !minorRef.current && data.approverIds.length > 0 ? data.approverIds : undefined,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
onCompleted(response) {
|
onCompleted(response) {
|
||||||
@@ -145,9 +148,19 @@ export function PublishFindingListDialog({
|
|||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
variant="secondary"
|
||||||
|
icon={IconUpload}
|
||||||
|
onClick={() => { minorRef.current = true; }}
|
||||||
|
disabled={isPublishing}
|
||||||
|
>
|
||||||
|
{__("Publish as minor")}
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
icon={hasApprovers ? IconSend : IconUpload}
|
icon={hasApprovers ? IconSend : IconUpload}
|
||||||
|
onClick={() => { minorRef.current = false; }}
|
||||||
disabled={isPublishing}
|
disabled={isPublishing}
|
||||||
>
|
>
|
||||||
{hasApprovers ? __("Request approval") : __("Publish")}
|
{hasApprovers ? __("Request approval") : __("Publish")}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import {
|
|||||||
useToast,
|
useToast,
|
||||||
} from "@probo/ui";
|
} from "@probo/ui";
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import { useMemo } from "react";
|
import { useMemo, useRef } from "react";
|
||||||
import { useMutation } from "react-relay";
|
import { useMutation } from "react-relay";
|
||||||
import { graphql } from "relay-runtime";
|
import { graphql } from "relay-runtime";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
@@ -83,6 +83,8 @@ export function PublishObligationListDialog({
|
|||||||
const [publish, isPublishing]
|
const [publish, isPublishing]
|
||||||
= useMutation<PublishObligationListDialogMutation>(publishMutation);
|
= useMutation<PublishObligationListDialogMutation>(publishMutation);
|
||||||
|
|
||||||
|
const minorRef = useRef(false);
|
||||||
|
|
||||||
const approverIds = watch("approverIds");
|
const approverIds = watch("approverIds");
|
||||||
const hasApprovers = approverIds.length > 0;
|
const hasApprovers = approverIds.length > 0;
|
||||||
|
|
||||||
@@ -90,8 +92,9 @@ export function PublishObligationListDialog({
|
|||||||
publish({
|
publish({
|
||||||
variables: {
|
variables: {
|
||||||
input: {
|
input: {
|
||||||
|
minor: minorRef.current,
|
||||||
organizationId,
|
organizationId,
|
||||||
approverIds: data.approverIds.length > 0 ? data.approverIds : undefined,
|
approverIds: !minorRef.current && data.approverIds.length > 0 ? data.approverIds : undefined,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
onCompleted(response) {
|
onCompleted(response) {
|
||||||
@@ -145,9 +148,19 @@ export function PublishObligationListDialog({
|
|||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
variant="secondary"
|
||||||
|
icon={IconUpload}
|
||||||
|
onClick={() => { minorRef.current = true; }}
|
||||||
|
disabled={isPublishing}
|
||||||
|
>
|
||||||
|
{__("Publish as minor")}
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
icon={hasApprovers ? IconSend : IconUpload}
|
icon={hasApprovers ? IconSend : IconUpload}
|
||||||
|
onClick={() => { minorRef.current = false; }}
|
||||||
disabled={isPublishing}
|
disabled={isPublishing}
|
||||||
>
|
>
|
||||||
{hasApprovers ? __("Request approval") : __("Publish")}
|
{hasApprovers ? __("Request approval") : __("Publish")}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import {
|
|||||||
useToast,
|
useToast,
|
||||||
} from "@probo/ui";
|
} from "@probo/ui";
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import { useMemo } from "react";
|
import { useMemo, useRef } from "react";
|
||||||
import { useMutation } from "react-relay";
|
import { useMutation } from "react-relay";
|
||||||
import { graphql } from "relay-runtime";
|
import { graphql } from "relay-runtime";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
@@ -83,6 +83,8 @@ export function PublishDataProtectionImpactAssessmentListDialog({
|
|||||||
const [publish, isPublishing]
|
const [publish, isPublishing]
|
||||||
= useMutation<PublishDataProtectionImpactAssessmentListDialogMutation>(publishMutation);
|
= useMutation<PublishDataProtectionImpactAssessmentListDialogMutation>(publishMutation);
|
||||||
|
|
||||||
|
const minorRef = useRef(false);
|
||||||
|
|
||||||
const approverIds = watch("approverIds");
|
const approverIds = watch("approverIds");
|
||||||
const hasApprovers = approverIds.length > 0;
|
const hasApprovers = approverIds.length > 0;
|
||||||
|
|
||||||
@@ -90,8 +92,9 @@ export function PublishDataProtectionImpactAssessmentListDialog({
|
|||||||
publish({
|
publish({
|
||||||
variables: {
|
variables: {
|
||||||
input: {
|
input: {
|
||||||
|
minor: minorRef.current,
|
||||||
organizationId,
|
organizationId,
|
||||||
approverIds: data.approverIds.length > 0 ? data.approverIds : undefined,
|
approverIds: !minorRef.current && data.approverIds.length > 0 ? data.approverIds : undefined,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
onCompleted(response) {
|
onCompleted(response) {
|
||||||
@@ -145,9 +148,19 @@ export function PublishDataProtectionImpactAssessmentListDialog({
|
|||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
variant="secondary"
|
||||||
|
icon={IconUpload}
|
||||||
|
onClick={() => { minorRef.current = true; }}
|
||||||
|
disabled={isPublishing}
|
||||||
|
>
|
||||||
|
{__("Publish as minor")}
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
icon={hasApprovers ? IconSend : IconUpload}
|
icon={hasApprovers ? IconSend : IconUpload}
|
||||||
|
onClick={() => { minorRef.current = false; }}
|
||||||
disabled={isPublishing}
|
disabled={isPublishing}
|
||||||
>
|
>
|
||||||
{hasApprovers ? __("Request approval") : __("Publish")}
|
{hasApprovers ? __("Request approval") : __("Publish")}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import {
|
|||||||
useToast,
|
useToast,
|
||||||
} from "@probo/ui";
|
} from "@probo/ui";
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import { useMemo } from "react";
|
import { useMemo, useRef } from "react";
|
||||||
import { useMutation } from "react-relay";
|
import { useMutation } from "react-relay";
|
||||||
import { graphql } from "relay-runtime";
|
import { graphql } from "relay-runtime";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
@@ -83,6 +83,8 @@ export function PublishProcessingActivityListDialog({
|
|||||||
const [publish, isPublishing]
|
const [publish, isPublishing]
|
||||||
= useMutation<PublishProcessingActivityListDialogMutation>(publishMutation);
|
= useMutation<PublishProcessingActivityListDialogMutation>(publishMutation);
|
||||||
|
|
||||||
|
const minorRef = useRef(false);
|
||||||
|
|
||||||
const approverIds = watch("approverIds");
|
const approverIds = watch("approverIds");
|
||||||
const hasApprovers = approverIds.length > 0;
|
const hasApprovers = approverIds.length > 0;
|
||||||
|
|
||||||
@@ -90,8 +92,9 @@ export function PublishProcessingActivityListDialog({
|
|||||||
publish({
|
publish({
|
||||||
variables: {
|
variables: {
|
||||||
input: {
|
input: {
|
||||||
|
minor: minorRef.current,
|
||||||
organizationId,
|
organizationId,
|
||||||
approverIds: data.approverIds.length > 0 ? data.approverIds : undefined,
|
approverIds: !minorRef.current && data.approverIds.length > 0 ? data.approverIds : undefined,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
onCompleted(response) {
|
onCompleted(response) {
|
||||||
@@ -145,9 +148,19 @@ export function PublishProcessingActivityListDialog({
|
|||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
variant="secondary"
|
||||||
|
icon={IconUpload}
|
||||||
|
onClick={() => { minorRef.current = true; }}
|
||||||
|
disabled={isPublishing}
|
||||||
|
>
|
||||||
|
{__("Publish as minor")}
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
icon={hasApprovers ? IconSend : IconUpload}
|
icon={hasApprovers ? IconSend : IconUpload}
|
||||||
|
onClick={() => { minorRef.current = false; }}
|
||||||
disabled={isPublishing}
|
disabled={isPublishing}
|
||||||
>
|
>
|
||||||
{hasApprovers ? __("Request approval") : __("Publish")}
|
{hasApprovers ? __("Request approval") : __("Publish")}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import {
|
|||||||
useToast,
|
useToast,
|
||||||
} from "@probo/ui";
|
} from "@probo/ui";
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import { useMemo } from "react";
|
import { useMemo, useRef } from "react";
|
||||||
import { useMutation } from "react-relay";
|
import { useMutation } from "react-relay";
|
||||||
import { graphql } from "relay-runtime";
|
import { graphql } from "relay-runtime";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
@@ -83,6 +83,8 @@ export function PublishTransferImpactAssessmentListDialog({
|
|||||||
const [publish, isPublishing]
|
const [publish, isPublishing]
|
||||||
= useMutation<PublishTransferImpactAssessmentListDialogMutation>(publishMutation);
|
= useMutation<PublishTransferImpactAssessmentListDialogMutation>(publishMutation);
|
||||||
|
|
||||||
|
const minorRef = useRef(false);
|
||||||
|
|
||||||
const approverIds = watch("approverIds");
|
const approverIds = watch("approverIds");
|
||||||
const hasApprovers = approverIds.length > 0;
|
const hasApprovers = approverIds.length > 0;
|
||||||
|
|
||||||
@@ -90,8 +92,9 @@ export function PublishTransferImpactAssessmentListDialog({
|
|||||||
publish({
|
publish({
|
||||||
variables: {
|
variables: {
|
||||||
input: {
|
input: {
|
||||||
|
minor: minorRef.current,
|
||||||
organizationId,
|
organizationId,
|
||||||
approverIds: data.approverIds.length > 0 ? data.approverIds : undefined,
|
approverIds: !minorRef.current && data.approverIds.length > 0 ? data.approverIds : undefined,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
onCompleted(response) {
|
onCompleted(response) {
|
||||||
@@ -145,9 +148,19 @@ export function PublishTransferImpactAssessmentListDialog({
|
|||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
variant="secondary"
|
||||||
|
icon={IconUpload}
|
||||||
|
onClick={() => { minorRef.current = true; }}
|
||||||
|
disabled={isPublishing}
|
||||||
|
>
|
||||||
|
{__("Publish as minor")}
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
icon={hasApprovers ? IconSend : IconUpload}
|
icon={hasApprovers ? IconSend : IconUpload}
|
||||||
|
onClick={() => { minorRef.current = false; }}
|
||||||
disabled={isPublishing}
|
disabled={isPublishing}
|
||||||
>
|
>
|
||||||
{hasApprovers ? __("Request approval") : __("Publish")}
|
{hasApprovers ? __("Request approval") : __("Publish")}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import {
|
|||||||
useToast,
|
useToast,
|
||||||
} from "@probo/ui";
|
} from "@probo/ui";
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import { useMemo } from "react";
|
import { useMemo, useRef } from "react";
|
||||||
import { useMutation } from "react-relay";
|
import { useMutation } from "react-relay";
|
||||||
import { graphql } from "relay-runtime";
|
import { graphql } from "relay-runtime";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
@@ -84,6 +84,8 @@ export function PublishRiskListDialog({
|
|||||||
const [publish, isPublishing]
|
const [publish, isPublishing]
|
||||||
= useMutation<PublishRiskListDialogMutation>(publishMutation);
|
= useMutation<PublishRiskListDialogMutation>(publishMutation);
|
||||||
|
|
||||||
|
const minorRef = useRef(false);
|
||||||
|
|
||||||
const approverIds = watch("approverIds");
|
const approverIds = watch("approverIds");
|
||||||
const hasApprovers = approverIds.length > 0;
|
const hasApprovers = approverIds.length > 0;
|
||||||
|
|
||||||
@@ -91,8 +93,9 @@ export function PublishRiskListDialog({
|
|||||||
publish({
|
publish({
|
||||||
variables: {
|
variables: {
|
||||||
input: {
|
input: {
|
||||||
|
minor: minorRef.current,
|
||||||
organizationId,
|
organizationId,
|
||||||
approverIds: data.approverIds.length > 0 ? data.approverIds : undefined,
|
approverIds: !minorRef.current && data.approverIds.length > 0 ? data.approverIds : undefined,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
onCompleted(response) {
|
onCompleted(response) {
|
||||||
@@ -146,9 +149,19 @@ export function PublishRiskListDialog({
|
|||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
variant="secondary"
|
||||||
|
icon={IconUpload}
|
||||||
|
onClick={() => { minorRef.current = true; }}
|
||||||
|
disabled={isPublishing}
|
||||||
|
>
|
||||||
|
{__("Publish as minor")}
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
icon={hasApprovers ? IconSend : IconUpload}
|
icon={hasApprovers ? IconSend : IconUpload}
|
||||||
|
onClick={() => { minorRef.current = false; }}
|
||||||
disabled={isPublishing}
|
disabled={isPublishing}
|
||||||
>
|
>
|
||||||
{hasApprovers ? __("Request approval") : __("Publish")}
|
{hasApprovers ? __("Request approval") : __("Publish")}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import {
|
|||||||
useToast,
|
useToast,
|
||||||
} from "@probo/ui";
|
} from "@probo/ui";
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import { useMemo } from "react";
|
import { useMemo, useRef } from "react";
|
||||||
import { useMutation } from "react-relay";
|
import { useMutation } from "react-relay";
|
||||||
import { graphql } from "relay-runtime";
|
import { graphql } from "relay-runtime";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
@@ -85,6 +85,8 @@ export function PublishStatementOfApplicabilityDialog({
|
|||||||
const [publish, isPublishing]
|
const [publish, isPublishing]
|
||||||
= useMutation<PublishStatementOfApplicabilityDialogMutation>(publishMutation);
|
= useMutation<PublishStatementOfApplicabilityDialogMutation>(publishMutation);
|
||||||
|
|
||||||
|
const minorRef = useRef(false);
|
||||||
|
|
||||||
const approverIds = watch("approverIds");
|
const approverIds = watch("approverIds");
|
||||||
const hasApprovers = approverIds.length > 0;
|
const hasApprovers = approverIds.length > 0;
|
||||||
|
|
||||||
@@ -92,8 +94,9 @@ export function PublishStatementOfApplicabilityDialog({
|
|||||||
publish({
|
publish({
|
||||||
variables: {
|
variables: {
|
||||||
input: {
|
input: {
|
||||||
|
minor: minorRef.current,
|
||||||
statementOfApplicabilityId,
|
statementOfApplicabilityId,
|
||||||
approverIds: data.approverIds.length > 0 ? data.approverIds : undefined,
|
approverIds: !minorRef.current && data.approverIds.length > 0 ? data.approverIds : undefined,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
onCompleted(response) {
|
onCompleted(response) {
|
||||||
@@ -147,9 +150,19 @@ export function PublishStatementOfApplicabilityDialog({
|
|||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
variant="secondary"
|
||||||
|
icon={IconUpload}
|
||||||
|
onClick={() => { minorRef.current = true; }}
|
||||||
|
disabled={isPublishing}
|
||||||
|
>
|
||||||
|
{__("Publish as minor")}
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
icon={hasApprovers ? IconSend : IconUpload}
|
icon={hasApprovers ? IconSend : IconUpload}
|
||||||
|
onClick={() => { minorRef.current = false; }}
|
||||||
disabled={isPublishing}
|
disabled={isPublishing}
|
||||||
>
|
>
|
||||||
{hasApprovers ? __("Request approval") : __("Publish")}
|
{hasApprovers ? __("Request approval") : __("Publish")}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import {
|
|||||||
useToast,
|
useToast,
|
||||||
} from "@probo/ui";
|
} from "@probo/ui";
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import { useMemo } from "react";
|
import { useMemo, useRef } from "react";
|
||||||
import { useMutation } from "react-relay";
|
import { useMutation } from "react-relay";
|
||||||
import { graphql } from "relay-runtime";
|
import { graphql } from "relay-runtime";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
@@ -84,6 +84,8 @@ export function PublishVendorListDialog({
|
|||||||
const [publish, isPublishing]
|
const [publish, isPublishing]
|
||||||
= useMutation<PublishVendorListDialogMutation>(publishMutation);
|
= useMutation<PublishVendorListDialogMutation>(publishMutation);
|
||||||
|
|
||||||
|
const minorRef = useRef(false);
|
||||||
|
|
||||||
const approverIds = watch("approverIds");
|
const approverIds = watch("approverIds");
|
||||||
const hasApprovers = approverIds.length > 0;
|
const hasApprovers = approverIds.length > 0;
|
||||||
|
|
||||||
@@ -91,8 +93,9 @@ export function PublishVendorListDialog({
|
|||||||
publish({
|
publish({
|
||||||
variables: {
|
variables: {
|
||||||
input: {
|
input: {
|
||||||
|
minor: minorRef.current,
|
||||||
organizationId,
|
organizationId,
|
||||||
approverIds: data.approverIds.length > 0 ? data.approverIds : undefined,
|
approverIds: !minorRef.current && data.approverIds.length > 0 ? data.approverIds : undefined,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
onCompleted(response) {
|
onCompleted(response) {
|
||||||
@@ -146,9 +149,19 @@ export function PublishVendorListDialog({
|
|||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
variant="secondary"
|
||||||
|
icon={IconUpload}
|
||||||
|
onClick={() => { minorRef.current = true; }}
|
||||||
|
disabled={isPublishing}
|
||||||
|
>
|
||||||
|
{__("Publish as minor")}
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
icon={hasApprovers ? IconSend : IconUpload}
|
icon={hasApprovers ? IconSend : IconUpload}
|
||||||
|
onClick={() => { minorRef.current = false; }}
|
||||||
disabled={isPublishing}
|
disabled={isPublishing}
|
||||||
>
|
>
|
||||||
{hasApprovers ? __("Request approval") : __("Publish")}
|
{hasApprovers ? __("Request approval") : __("Publish")}
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ func TestAsset_PublishAssetList(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -161,6 +162,7 @@ func TestAsset_PublishAssetList(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
"approverIds": []string{owner.GetProfileID().String()},
|
"approverIds": []string{owner.GetProfileID().String()},
|
||||||
},
|
},
|
||||||
@@ -221,6 +223,7 @@ func TestAsset_PublishAssetList(t *testing.T) {
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": secondOwner.GetOrganizationID(),
|
"organizationId": secondOwner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -284,6 +287,7 @@ func TestAsset_PublishAssetList(t *testing.T) {
|
|||||||
publishQuery,
|
publishQuery,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": thirdOwner.GetOrganizationID(),
|
"organizationId": thirdOwner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -356,6 +360,7 @@ func TestAsset_PublishAssetList_RBAC(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ func TestDatum_PublishDataList(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -162,6 +163,7 @@ func TestDatum_PublishDataList(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
"approverIds": []string{owner.GetProfileID().String()},
|
"approverIds": []string{owner.GetProfileID().String()},
|
||||||
},
|
},
|
||||||
@@ -223,6 +225,7 @@ func TestDatum_PublishDataList(t *testing.T) {
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": secondOwner.GetOrganizationID(),
|
"organizationId": secondOwner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -287,6 +290,7 @@ func TestDatum_PublishDataList(t *testing.T) {
|
|||||||
publishQuery,
|
publishQuery,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": thirdOwner.GetOrganizationID(),
|
"organizationId": thirdOwner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -360,6 +364,7 @@ func TestDatum_PublishDataList_RBAC(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -92,8 +92,8 @@ func approveTestDocument(t *testing.T, owner *testutil.Client, docID string) {
|
|||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
requestQuery := `
|
requestQuery := `
|
||||||
mutation RequestApproval($input: RequestDocumentVersionApprovalInput!) {
|
mutation RequestApproval($input: PublishDocumentInput!) {
|
||||||
requestDocumentVersionApproval(input: $input) {
|
publishDocument(input: $input) {
|
||||||
approvalQuorum {
|
approvalQuorum {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
@@ -106,6 +106,7 @@ func approveTestDocument(t *testing.T, owner *testutil.Client, docID string) {
|
|||||||
|
|
||||||
_, err := owner.Do(requestQuery, map[string]any{
|
_, err := owner.Do(requestQuery, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"documentId": docID,
|
"documentId": docID,
|
||||||
"approverIds": []string{approverID},
|
"approverIds": []string{approverID},
|
||||||
"changelog": "Test changelog",
|
"changelog": "Test changelog",
|
||||||
@@ -472,8 +473,8 @@ func TestDocumentVersion_BulkPublish(t *testing.T) {
|
|||||||
docID2, _ := createTestDocument(t, owner)
|
docID2, _ := createTestDocument(t, owner)
|
||||||
|
|
||||||
query := `
|
query := `
|
||||||
mutation BulkPublishMajorDocumentVersions($input: BulkPublishDocumentVersionsInput!) {
|
mutation BulkPublishDocuments($input: BulkPublishDocumentsInput!) {
|
||||||
bulkPublishMajorDocumentVersions(input: $input) {
|
bulkPublishDocuments(input: $input) {
|
||||||
documentVersions {
|
documentVersions {
|
||||||
id
|
id
|
||||||
status
|
status
|
||||||
@@ -483,24 +484,25 @@ func TestDocumentVersion_BulkPublish(t *testing.T) {
|
|||||||
`
|
`
|
||||||
|
|
||||||
var result struct {
|
var result struct {
|
||||||
BulkPublishMajorDocumentVersions struct {
|
BulkPublishDocuments struct {
|
||||||
DocumentVersions []struct {
|
DocumentVersions []struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
} `json:"documentVersions"`
|
} `json:"documentVersions"`
|
||||||
} `json:"bulkPublishMajorDocumentVersions"`
|
} `json:"bulkPublishDocuments"`
|
||||||
}
|
}
|
||||||
|
|
||||||
err := owner.Execute(query, map[string]any{
|
err := owner.Execute(query, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"documentIds": []string{docID1, docID2},
|
"documentIds": []string{docID1, docID2},
|
||||||
"changelog": "Bulk publish release",
|
"changelog": "Bulk publish release",
|
||||||
},
|
},
|
||||||
}, &result)
|
}, &result)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, 2, len(result.BulkPublishMajorDocumentVersions.DocumentVersions))
|
assert.Equal(t, 2, len(result.BulkPublishDocuments.DocumentVersions))
|
||||||
for _, dv := range result.BulkPublishMajorDocumentVersions.DocumentVersions {
|
for _, dv := range result.BulkPublishDocuments.DocumentVersions {
|
||||||
assert.Equal(t, "PUBLISHED", dv.Status)
|
assert.Equal(t, "PUBLISHED", dv.Status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -515,8 +517,8 @@ func TestDocumentVersion_BulkPublishRequestsApproval(t *testing.T) {
|
|||||||
docID := createTestDocumentWithApprovers(t, owner, []string{approverID})
|
docID := createTestDocumentWithApprovers(t, owner, []string{approverID})
|
||||||
|
|
||||||
query := `
|
query := `
|
||||||
mutation BulkPublishMajorDocumentVersions($input: BulkPublishDocumentVersionsInput!) {
|
mutation BulkPublishDocuments($input: BulkPublishDocumentsInput!) {
|
||||||
bulkPublishMajorDocumentVersions(input: $input) {
|
bulkPublishDocuments(input: $input) {
|
||||||
documentVersions {
|
documentVersions {
|
||||||
id
|
id
|
||||||
status
|
status
|
||||||
@@ -528,26 +530,27 @@ func TestDocumentVersion_BulkPublishRequestsApproval(t *testing.T) {
|
|||||||
`
|
`
|
||||||
|
|
||||||
var result struct {
|
var result struct {
|
||||||
BulkPublishMajorDocumentVersions struct {
|
BulkPublishDocuments struct {
|
||||||
DocumentVersions []struct {
|
DocumentVersions []struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Major int `json:"major"`
|
Major int `json:"major"`
|
||||||
Minor int `json:"minor"`
|
Minor int `json:"minor"`
|
||||||
} `json:"documentVersions"`
|
} `json:"documentVersions"`
|
||||||
} `json:"bulkPublishMajorDocumentVersions"`
|
} `json:"bulkPublishDocuments"`
|
||||||
}
|
}
|
||||||
|
|
||||||
err := owner.Execute(query, map[string]any{
|
err := owner.Execute(query, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"documentIds": []string{docID},
|
"documentIds": []string{docID},
|
||||||
"changelog": "Needs approval",
|
"changelog": "Needs approval",
|
||||||
},
|
},
|
||||||
}, &result)
|
}, &result)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Len(t, result.BulkPublishMajorDocumentVersions.DocumentVersions, 1)
|
require.Len(t, result.BulkPublishDocuments.DocumentVersions, 1)
|
||||||
dv := result.BulkPublishMajorDocumentVersions.DocumentVersions[0]
|
dv := result.BulkPublishDocuments.DocumentVersions[0]
|
||||||
assert.Equal(t, "PENDING_APPROVAL", dv.Status)
|
assert.Equal(t, "PENDING_APPROVAL", dv.Status)
|
||||||
assert.Equal(t, 1, dv.Major)
|
assert.Equal(t, 1, dv.Major)
|
||||||
assert.Equal(t, 0, dv.Minor)
|
assert.Equal(t, 0, dv.Minor)
|
||||||
@@ -563,13 +566,14 @@ func TestDocumentVersion_BulkPublishSkipsPendingApproval(t *testing.T) {
|
|||||||
docID := createTestDocumentWithApprovers(t, owner, []string{approverID})
|
docID := createTestDocumentWithApprovers(t, owner, []string{approverID})
|
||||||
|
|
||||||
_, err := owner.Do(`
|
_, err := owner.Do(`
|
||||||
mutation($input: BulkPublishDocumentVersionsInput!) {
|
mutation($input: BulkPublishDocumentsInput!) {
|
||||||
bulkPublishMajorDocumentVersions(input: $input) {
|
bulkPublishDocuments(input: $input) {
|
||||||
documentVersions { id }
|
documentVersions { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, map[string]any{
|
`, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"documentIds": []string{docID},
|
"documentIds": []string{docID},
|
||||||
"changelog": "First approval request",
|
"changelog": "First approval request",
|
||||||
},
|
},
|
||||||
@@ -578,28 +582,29 @@ func TestDocumentVersion_BulkPublishSkipsPendingApproval(t *testing.T) {
|
|||||||
|
|
||||||
// Bulk publish again — should skip the pending document and return empty
|
// Bulk publish again — should skip the pending document and return empty
|
||||||
var result struct {
|
var result struct {
|
||||||
BulkPublishMajorDocumentVersions struct {
|
BulkPublishDocuments struct {
|
||||||
DocumentVersions []struct {
|
DocumentVersions []struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
} `json:"documentVersions"`
|
} `json:"documentVersions"`
|
||||||
} `json:"bulkPublishMajorDocumentVersions"`
|
} `json:"bulkPublishDocuments"`
|
||||||
}
|
}
|
||||||
|
|
||||||
err = owner.Execute(`
|
err = owner.Execute(`
|
||||||
mutation($input: BulkPublishDocumentVersionsInput!) {
|
mutation($input: BulkPublishDocumentsInput!) {
|
||||||
bulkPublishMajorDocumentVersions(input: $input) {
|
bulkPublishDocuments(input: $input) {
|
||||||
documentVersions { id }
|
documentVersions { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, map[string]any{
|
`, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"documentIds": []string{docID},
|
"documentIds": []string{docID},
|
||||||
"changelog": "Second attempt",
|
"changelog": "Second attempt",
|
||||||
},
|
},
|
||||||
}, &result)
|
}, &result)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Empty(t, result.BulkPublishMajorDocumentVersions.DocumentVersions)
|
assert.Empty(t, result.BulkPublishDocuments.DocumentVersions)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDocumentVersion_BulkPublishMinorSkipsPendingApproval(t *testing.T) {
|
func TestDocumentVersion_BulkPublishMinorSkipsPendingApproval(t *testing.T) {
|
||||||
@@ -628,13 +633,14 @@ func TestDocumentVersion_BulkPublishMinorSkipsPendingApproval(t *testing.T) {
|
|||||||
// Request approval to put it in PENDING_APPROVAL
|
// Request approval to put it in PENDING_APPROVAL
|
||||||
approverID := getOwnerProfileID(t, owner)
|
approverID := getOwnerProfileID(t, owner)
|
||||||
_, err = owner.Do(`
|
_, err = owner.Do(`
|
||||||
mutation($input: RequestDocumentVersionApprovalInput!) {
|
mutation($input: PublishDocumentInput!) {
|
||||||
requestDocumentVersionApproval(input: $input) {
|
publishDocument(input: $input) {
|
||||||
approvalQuorum { id }
|
approvalQuorum { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, map[string]any{
|
`, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"documentId": docID,
|
"documentId": docID,
|
||||||
"approverIds": []string{approverID},
|
"approverIds": []string{approverID},
|
||||||
"changelog": "Approval request",
|
"changelog": "Approval request",
|
||||||
@@ -644,28 +650,29 @@ func TestDocumentVersion_BulkPublishMinorSkipsPendingApproval(t *testing.T) {
|
|||||||
|
|
||||||
// Bulk publish minor — should skip the pending document
|
// Bulk publish minor — should skip the pending document
|
||||||
var result struct {
|
var result struct {
|
||||||
BulkPublishMinorDocumentVersions struct {
|
BulkPublishDocuments struct {
|
||||||
DocumentVersions []struct {
|
DocumentVersions []struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
} `json:"documentVersions"`
|
} `json:"documentVersions"`
|
||||||
} `json:"bulkPublishMinorDocumentVersions"`
|
} `json:"bulkPublishDocuments"`
|
||||||
}
|
}
|
||||||
|
|
||||||
err = owner.Execute(`
|
err = owner.Execute(`
|
||||||
mutation($input: BulkPublishDocumentVersionsInput!) {
|
mutation($input: BulkPublishDocumentsInput!) {
|
||||||
bulkPublishMinorDocumentVersions(input: $input) {
|
bulkPublishDocuments(input: $input) {
|
||||||
documentVersions { id }
|
documentVersions { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, map[string]any{
|
`, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": true,
|
||||||
"documentIds": []string{docID},
|
"documentIds": []string{docID},
|
||||||
"changelog": "Minor publish attempt",
|
"changelog": "Minor publish attempt",
|
||||||
},
|
},
|
||||||
}, &result)
|
}, &result)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Empty(t, result.BulkPublishMinorDocumentVersions.DocumentVersions)
|
assert.Empty(t, result.BulkPublishDocuments.DocumentVersions)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDocumentVersion_BulkRequestSignatures(t *testing.T) {
|
func TestDocumentVersion_BulkRequestSignatures(t *testing.T) {
|
||||||
@@ -883,13 +890,14 @@ func TestDocumentVersion_VoidApproval(t *testing.T) {
|
|||||||
|
|
||||||
// Request approval
|
// Request approval
|
||||||
_, err := owner.Do(`
|
_, err := owner.Do(`
|
||||||
mutation($input: RequestDocumentVersionApprovalInput!) {
|
mutation($input: PublishDocumentInput!) {
|
||||||
requestDocumentVersionApproval(input: $input) {
|
publishDocument(input: $input) {
|
||||||
approvalQuorum { id }
|
approvalQuorum { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, map[string]any{
|
`, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"documentId": docID,
|
"documentId": docID,
|
||||||
"approverIds": []string{approverID},
|
"approverIds": []string{approverID},
|
||||||
"changelog": "Test changelog",
|
"changelog": "Test changelog",
|
||||||
@@ -1034,13 +1042,14 @@ func TestDocumentVersion_RejectApproval(t *testing.T) {
|
|||||||
|
|
||||||
// Request approval — version should bump to 1.0
|
// Request approval — version should bump to 1.0
|
||||||
_, err := owner.Do(`
|
_, err := owner.Do(`
|
||||||
mutation($input: RequestDocumentVersionApprovalInput!) {
|
mutation($input: PublishDocumentInput!) {
|
||||||
requestDocumentVersionApproval(input: $input) {
|
publishDocument(input: $input) {
|
||||||
approvalQuorum { id }
|
approvalQuorum { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, map[string]any{
|
`, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"documentId": docID,
|
"documentId": docID,
|
||||||
"approverIds": []string{approverID},
|
"approverIds": []string{approverID},
|
||||||
"changelog": "Test changelog",
|
"changelog": "Test changelog",
|
||||||
@@ -1181,13 +1190,14 @@ func TestDocumentVersion_PublishBlockedWhenPendingApproval(t *testing.T) {
|
|||||||
|
|
||||||
// Request approval (puts version in PENDING_APPROVAL)
|
// Request approval (puts version in PENDING_APPROVAL)
|
||||||
_, err := owner.Do(`
|
_, err := owner.Do(`
|
||||||
mutation($input: RequestDocumentVersionApprovalInput!) {
|
mutation($input: PublishDocumentInput!) {
|
||||||
requestDocumentVersionApproval(input: $input) {
|
publishDocument(input: $input) {
|
||||||
approvalQuorum { id }
|
approvalQuorum { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, map[string]any{
|
`, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"documentId": docID,
|
"documentId": docID,
|
||||||
"approverIds": []string{approverID},
|
"approverIds": []string{approverID},
|
||||||
"changelog": "Test changelog",
|
"changelog": "Test changelog",
|
||||||
@@ -1199,13 +1209,14 @@ func TestDocumentVersion_PublishBlockedWhenPendingApproval(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
_, err := owner.Do(`
|
_, err := owner.Do(`
|
||||||
mutation($input: PublishMajorDocumentVersionInput!) {
|
mutation($input: PublishDocumentInput!) {
|
||||||
publishMajorDocumentVersion(input: $input) {
|
publishDocument(input: $input) {
|
||||||
documentVersion { id }
|
documentVersion { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, map[string]any{
|
`, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"documentId": docID,
|
"documentId": docID,
|
||||||
"changelog": "Major release",
|
"changelog": "Major release",
|
||||||
},
|
},
|
||||||
@@ -1217,13 +1228,14 @@ func TestDocumentVersion_PublishBlockedWhenPendingApproval(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
_, err := owner.Do(`
|
_, err := owner.Do(`
|
||||||
mutation($input: PublishMinorDocumentVersionInput!) {
|
mutation($input: PublishDocumentInput!) {
|
||||||
publishMinorDocumentVersion(input: $input) {
|
publishDocument(input: $input) {
|
||||||
documentVersion { id }
|
documentVersion { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, map[string]any{
|
`, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": true,
|
||||||
"documentId": docID,
|
"documentId": docID,
|
||||||
"changelog": "Minor release",
|
"changelog": "Minor release",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ func TestDataProtectionImpactAssessment_PublishList(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -150,6 +151,7 @@ func TestDataProtectionImpactAssessment_PublishList(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
"approverIds": []string{owner.GetProfileID().String()},
|
"approverIds": []string{owner.GetProfileID().String()},
|
||||||
},
|
},
|
||||||
@@ -199,6 +201,7 @@ func TestDataProtectionImpactAssessment_PublishList(t *testing.T) {
|
|||||||
publishQuery,
|
publishQuery,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -265,6 +268,7 @@ func TestDataProtectionImpactAssessment_PublishList_RBAC(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -317,13 +317,14 @@ func TestEmployeeDocument_SignableDocuments(t *testing.T) {
|
|||||||
ownerProfileID := owner.GetProfileID().String()
|
ownerProfileID := owner.GetProfileID().String()
|
||||||
|
|
||||||
_, err := owner.Do(`
|
_, err := owner.Do(`
|
||||||
mutation($input: RequestDocumentVersionApprovalInput!) {
|
mutation($input: PublishDocumentInput!) {
|
||||||
requestDocumentVersionApproval(input: $input) {
|
publishDocument(input: $input) {
|
||||||
approvalQuorum { id }
|
approvalQuorum { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, map[string]any{
|
`, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"documentId": docID,
|
"documentId": docID,
|
||||||
"approverIds": []string{ownerProfileID},
|
"approverIds": []string{ownerProfileID},
|
||||||
"changelog": "Test changelog",
|
"changelog": "Test changelog",
|
||||||
@@ -373,13 +374,14 @@ func TestEmployeeDocument_FilterModeIsolation(t *testing.T) {
|
|||||||
adminProfileID := admin.GetProfileID().String()
|
adminProfileID := admin.GetProfileID().String()
|
||||||
|
|
||||||
_, err := owner.Do(`
|
_, err := owner.Do(`
|
||||||
mutation($input: RequestDocumentVersionApprovalInput!) {
|
mutation($input: PublishDocumentInput!) {
|
||||||
requestDocumentVersionApproval(input: $input) {
|
publishDocument(input: $input) {
|
||||||
approvalQuorum { id }
|
approvalQuorum { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, map[string]any{
|
`, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"documentId": docID,
|
"documentId": docID,
|
||||||
"approverIds": []string{adminProfileID},
|
"approverIds": []string{adminProfileID},
|
||||||
"changelog": "Test changelog",
|
"changelog": "Test changelog",
|
||||||
@@ -569,13 +571,14 @@ func TestEmployeeDocument_ApproverFilterModeIsolation(t *testing.T) {
|
|||||||
ownerProfileID := owner.GetProfileID().String()
|
ownerProfileID := owner.GetProfileID().String()
|
||||||
|
|
||||||
_, err := owner.Do(`
|
_, err := owner.Do(`
|
||||||
mutation($input: RequestDocumentVersionApprovalInput!) {
|
mutation($input: PublishDocumentInput!) {
|
||||||
requestDocumentVersionApproval(input: $input) {
|
publishDocument(input: $input) {
|
||||||
approvalQuorum { id }
|
approvalQuorum { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, map[string]any{
|
`, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"documentId": docID,
|
"documentId": docID,
|
||||||
"approverIds": []string{ownerProfileID},
|
"approverIds": []string{ownerProfileID},
|
||||||
"changelog": "Test changelog",
|
"changelog": "Test changelog",
|
||||||
@@ -791,13 +794,14 @@ func TestEmployeeDocument_UnapprovedDocument(t *testing.T) {
|
|||||||
ownerProfileID := owner.GetProfileID().String()
|
ownerProfileID := owner.GetProfileID().String()
|
||||||
|
|
||||||
_, err := owner.Do(`
|
_, err := owner.Do(`
|
||||||
mutation($input: RequestDocumentVersionApprovalInput!) {
|
mutation($input: PublishDocumentInput!) {
|
||||||
requestDocumentVersionApproval(input: $input) {
|
publishDocument(input: $input) {
|
||||||
approvalQuorum { id }
|
approvalQuorum { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, map[string]any{
|
`, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"documentId": docID,
|
"documentId": docID,
|
||||||
"approverIds": []string{ownerProfileID},
|
"approverIds": []string{ownerProfileID},
|
||||||
"changelog": "Test changelog",
|
"changelog": "Test changelog",
|
||||||
@@ -1032,13 +1036,14 @@ func TestEmployeeDocument_ApprovableDocumentNestedFields(t *testing.T) {
|
|||||||
ownerProfileID := owner.GetProfileID().String()
|
ownerProfileID := owner.GetProfileID().String()
|
||||||
|
|
||||||
_, err := owner.Do(`
|
_, err := owner.Do(`
|
||||||
mutation($input: RequestDocumentVersionApprovalInput!) {
|
mutation($input: PublishDocumentInput!) {
|
||||||
requestDocumentVersionApproval(input: $input) {
|
publishDocument(input: $input) {
|
||||||
approvalQuorum { id }
|
approvalQuorum { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, map[string]any{
|
`, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"documentId": docID,
|
"documentId": docID,
|
||||||
"approverIds": []string{ownerProfileID},
|
"approverIds": []string{ownerProfileID},
|
||||||
"changelog": "Test changelog",
|
"changelog": "Test changelog",
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ func TestFinding_PublishFindingList(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -159,6 +160,7 @@ func TestFinding_PublishFindingList(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
"approverIds": []string{owner.GetProfileID().String()},
|
"approverIds": []string{owner.GetProfileID().String()},
|
||||||
},
|
},
|
||||||
@@ -218,6 +220,7 @@ func TestFinding_PublishFindingList(t *testing.T) {
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": secondOwner.GetOrganizationID(),
|
"organizationId": secondOwner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -280,6 +283,7 @@ func TestFinding_PublishFindingList(t *testing.T) {
|
|||||||
publishQuery,
|
publishQuery,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": thirdOwner.GetOrganizationID(),
|
"organizationId": thirdOwner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -351,6 +355,7 @@ func TestFinding_PublishFindingList_RBAC(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ func TestObligation_PublishObligationList(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -159,6 +160,7 @@ func TestObligation_PublishObligationList(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
"approverIds": []string{owner.GetProfileID().String()},
|
"approverIds": []string{owner.GetProfileID().String()},
|
||||||
},
|
},
|
||||||
@@ -218,6 +220,7 @@ func TestObligation_PublishObligationList(t *testing.T) {
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": secondOwner.GetOrganizationID(),
|
"organizationId": secondOwner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -280,6 +283,7 @@ func TestObligation_PublishObligationList(t *testing.T) {
|
|||||||
publishQuery,
|
publishQuery,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": thirdOwner.GetOrganizationID(),
|
"organizationId": thirdOwner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -351,6 +355,7 @@ func TestObligation_PublishObligationList_RBAC(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ func TestProcessingActivity_PublishProcessingActivityList(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -153,6 +154,7 @@ func TestProcessingActivity_PublishProcessingActivityList(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
"approverIds": []string{owner.GetProfileID().String()},
|
"approverIds": []string{owner.GetProfileID().String()},
|
||||||
},
|
},
|
||||||
@@ -210,6 +212,7 @@ func TestProcessingActivity_PublishProcessingActivityList(t *testing.T) {
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": secondOwner.GetOrganizationID(),
|
"organizationId": secondOwner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -267,6 +270,7 @@ func TestProcessingActivity_PublishProcessingActivityList(t *testing.T) {
|
|||||||
publishQuery,
|
publishQuery,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": thirdOwner.GetOrganizationID(),
|
"organizationId": thirdOwner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -338,6 +342,7 @@ func TestProcessingActivity_PublishProcessingActivityList_RBAC(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ func TestRisk_PublishRiskList(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -150,6 +151,7 @@ func TestRisk_PublishRiskList(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
"approverIds": []string{owner.GetProfileID().String()},
|
"approverIds": []string{owner.GetProfileID().String()},
|
||||||
},
|
},
|
||||||
@@ -203,6 +205,7 @@ func TestRisk_PublishRiskList(t *testing.T) {
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -259,6 +262,7 @@ func TestRisk_PublishRiskList(t *testing.T) {
|
|||||||
publishQuery,
|
publishQuery,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -326,6 +330,7 @@ func TestRisk_PublishRiskList_RBAC(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ func TestStatementOfApplicability_CreateDocument(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"statementOfApplicabilityId": soaID,
|
"statementOfApplicabilityId": soaID,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -230,6 +231,7 @@ func TestStatementOfApplicability_CreateDocument(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"statementOfApplicabilityId": soaID,
|
"statementOfApplicabilityId": soaID,
|
||||||
"approverIds": []string{owner.GetProfileID().String()},
|
"approverIds": []string{owner.GetProfileID().String()},
|
||||||
},
|
},
|
||||||
@@ -291,6 +293,7 @@ func TestStatementOfApplicability_CreateDocument(t *testing.T) {
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"statementOfApplicabilityId": soaID,
|
"statementOfApplicabilityId": soaID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -355,6 +358,7 @@ func TestStatementOfApplicability_CreateDocument(t *testing.T) {
|
|||||||
createQuery,
|
createQuery,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"statementOfApplicabilityId": soaID,
|
"statementOfApplicabilityId": soaID,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -426,6 +430,7 @@ func TestStatementOfApplicability_CreateDocument_RBAC(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"statementOfApplicabilityId": soaID,
|
"statementOfApplicabilityId": soaID,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -465,6 +470,7 @@ func TestStatementOfApplicability_TenantIsolation(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"statementOfApplicabilityId": soaID,
|
"statementOfApplicabilityId": soaID,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ func TestTransferImpactAssessment_PublishList(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -150,6 +151,7 @@ func TestTransferImpactAssessment_PublishList(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
"approverIds": []string{owner.GetProfileID().String()},
|
"approverIds": []string{owner.GetProfileID().String()},
|
||||||
},
|
},
|
||||||
@@ -199,6 +201,7 @@ func TestTransferImpactAssessment_PublishList(t *testing.T) {
|
|||||||
publishQuery,
|
publishQuery,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -265,6 +268,7 @@ func TestTransferImpactAssessment_PublishList_RBAC(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ func TestVendor_PublishVendorList(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -150,6 +151,7 @@ func TestVendor_PublishVendorList(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
"approverIds": []string{owner.GetProfileID().String()},
|
"approverIds": []string{owner.GetProfileID().String()},
|
||||||
},
|
},
|
||||||
@@ -203,6 +205,7 @@ func TestVendor_PublishVendorList(t *testing.T) {
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -259,6 +262,7 @@ func TestVendor_PublishVendorList(t *testing.T) {
|
|||||||
publishQuery,
|
publishQuery,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -326,6 +330,7 @@ func TestVendor_PublishVendorList_RBAC(t *testing.T) {
|
|||||||
query,
|
query,
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
|
"minor": false,
|
||||||
"organizationId": owner.GetOrganizationID(),
|
"organizationId": owner.GetOrganizationID(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -43,6 +43,19 @@ export const description: INodeProperties[] = [
|
|||||||
default: '',
|
default: '',
|
||||||
description: 'Comma-separated list of approver profile IDs',
|
description: 'Comma-separated list of approver profile IDs',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Minor',
|
||||||
|
name: 'minor',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: ['asset'],
|
||||||
|
operation: ['publish'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: false,
|
||||||
|
description: 'Whether to publish as a minor version. Approvers are ignored when set. The list must already have a published major version.',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export async function execute(
|
export async function execute(
|
||||||
@@ -51,6 +64,7 @@ export async function execute(
|
|||||||
): Promise<INodeExecutionData> {
|
): Promise<INodeExecutionData> {
|
||||||
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
|
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
|
||||||
const approverIds = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
const approverIds = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
||||||
|
const minor = this.getNodeParameter('minor', itemIndex, false) as boolean;
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation PublishAssetList($input: PublishAssetListInput!) {
|
mutation PublishAssetList($input: PublishAssetListInput!) {
|
||||||
@@ -83,7 +97,7 @@ export async function execute(
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const input: Record<string, unknown> = { organizationId };
|
const input: Record<string, unknown> = { organizationId, minor };
|
||||||
|
|
||||||
if (approverIds) {
|
if (approverIds) {
|
||||||
input.approverIds = approverIds
|
input.approverIds = approverIds
|
||||||
|
|||||||
@@ -43,6 +43,19 @@ export const description: INodeProperties[] = [
|
|||||||
default: '',
|
default: '',
|
||||||
description: 'Comma-separated list of approver profile IDs',
|
description: 'Comma-separated list of approver profile IDs',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Minor',
|
||||||
|
name: 'minor',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: ['datum'],
|
||||||
|
operation: ['publish'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: false,
|
||||||
|
description: 'Whether to publish as a minor version. Approvers are ignored when set. The list must already have a published major version.',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export async function execute(
|
export async function execute(
|
||||||
@@ -51,6 +64,7 @@ export async function execute(
|
|||||||
): Promise<INodeExecutionData> {
|
): Promise<INodeExecutionData> {
|
||||||
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
|
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
|
||||||
const approverIds = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
const approverIds = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
||||||
|
const minor = this.getNodeParameter('minor', itemIndex, false) as boolean;
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation PublishDataList($input: PublishDataListInput!) {
|
mutation PublishDataList($input: PublishDataListInput!) {
|
||||||
@@ -83,7 +97,7 @@ export async function execute(
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const input: Record<string, unknown> = { organizationId };
|
const input: Record<string, unknown> = { organizationId, minor };
|
||||||
|
|
||||||
if (approverIds) {
|
if (approverIds) {
|
||||||
input.approverIds = approverIds
|
input.approverIds = approverIds
|
||||||
|
|||||||
@@ -25,9 +25,7 @@ import * as getAllVersionsOp from './getAllVersions.operation';
|
|||||||
import * as createDraftVersionOp from './createDraftVersion.operation';
|
import * as createDraftVersionOp from './createDraftVersion.operation';
|
||||||
import * as updateVersionOp from './updateVersion.operation';
|
import * as updateVersionOp from './updateVersion.operation';
|
||||||
import * as deleteDraftVersionOp from './deleteDraftVersion.operation';
|
import * as deleteDraftVersionOp from './deleteDraftVersion.operation';
|
||||||
import * as publishMajorVersionOp from './publishMajorVersion.operation';
|
import * as publishOp from './publish.operation';
|
||||||
import * as publishMinorVersionOp from './publishMinorVersion.operation';
|
|
||||||
import * as requestApprovalOp from './requestApproval.operation';
|
|
||||||
import * as voidApprovalOp from './voidApproval.operation';
|
import * as voidApprovalOp from './voidApproval.operation';
|
||||||
import * as getSignatureOp from './getSignature.operation';
|
import * as getSignatureOp from './getSignature.operation';
|
||||||
import * as getAllSignaturesOp from './getAllSignatures.operation';
|
import * as getAllSignaturesOp from './getAllSignatures.operation';
|
||||||
@@ -148,22 +146,10 @@ export const description: INodeProperties[] = [
|
|||||||
action: 'Get a document version',
|
action: 'Get a document version',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Publish Major Version',
|
name: 'Publish',
|
||||||
value: 'publishMajorVersion',
|
value: 'publish',
|
||||||
description: 'Publish a draft as a new major version',
|
description: 'Publish a draft document, request approval, or publish as minor',
|
||||||
action: 'Publish a major document version',
|
action: 'Publish a document',
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Publish Minor Version',
|
|
||||||
value: 'publishMinorVersion',
|
|
||||||
description: 'Publish a draft as a minor version',
|
|
||||||
action: 'Publish a minor document version',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Request Approval',
|
|
||||||
value: 'requestApproval',
|
|
||||||
description: 'Request approval for a document version',
|
|
||||||
action: 'Request document version approval',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Request Signature',
|
name: 'Request Signature',
|
||||||
@@ -216,9 +202,7 @@ export const description: INodeProperties[] = [
|
|||||||
...createDraftVersionOp.description,
|
...createDraftVersionOp.description,
|
||||||
...updateVersionOp.description,
|
...updateVersionOp.description,
|
||||||
...deleteDraftVersionOp.description,
|
...deleteDraftVersionOp.description,
|
||||||
...publishMajorVersionOp.description,
|
...publishOp.description,
|
||||||
...publishMinorVersionOp.description,
|
|
||||||
...requestApprovalOp.description,
|
|
||||||
...voidApprovalOp.description,
|
...voidApprovalOp.description,
|
||||||
...getSignatureOp.description,
|
...getSignatureOp.description,
|
||||||
...getAllSignaturesOp.description,
|
...getAllSignaturesOp.description,
|
||||||
@@ -244,9 +228,7 @@ export {
|
|||||||
createDraftVersionOp as createDraftVersion,
|
createDraftVersionOp as createDraftVersion,
|
||||||
updateVersionOp as updateVersion,
|
updateVersionOp as updateVersion,
|
||||||
deleteDraftVersionOp as deleteDraftVersion,
|
deleteDraftVersionOp as deleteDraftVersion,
|
||||||
publishMajorVersionOp as publishMajorVersion,
|
publishOp as publish,
|
||||||
publishMinorVersionOp as publishMinorVersion,
|
|
||||||
requestApprovalOp as requestApproval,
|
|
||||||
voidApprovalOp as voidApproval,
|
voidApprovalOp as voidApproval,
|
||||||
getSignatureOp as getSignature,
|
getSignatureOp as getSignature,
|
||||||
getAllSignaturesOp as getAllSignatures,
|
getAllSignaturesOp as getAllSignatures,
|
||||||
|
|||||||
@@ -23,13 +23,40 @@ export const description: INodeProperties[] = [
|
|||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['document'],
|
resource: ['document'],
|
||||||
operation: ['publishMajorVersion'],
|
operation: ['publish'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The ID of the document',
|
description: 'The ID of the document',
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Minor',
|
||||||
|
name: 'minor',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: ['document'],
|
||||||
|
operation: ['publish'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: false,
|
||||||
|
description: 'Whether to publish as a minor version. Approvers are ignored when set. The document must already have a published major version.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Approver IDs',
|
||||||
|
name: 'approverIds',
|
||||||
|
type: 'string',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: ['document'],
|
||||||
|
operation: ['publish'],
|
||||||
|
minor: [false],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: 'Comma-separated list of approver profile IDs. When provided, an approval is requested instead of publishing immediately.',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Changelog',
|
displayName: 'Changelog',
|
||||||
name: 'changelog',
|
name: 'changelog',
|
||||||
@@ -40,11 +67,12 @@ export const description: INodeProperties[] = [
|
|||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['document'],
|
resource: ['document'],
|
||||||
operation: ['publishMajorVersion'],
|
operation: ['publish'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The changelog for this version',
|
description: 'The changelog for this version',
|
||||||
|
required: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -53,11 +81,13 @@ export async function execute(
|
|||||||
itemIndex: number,
|
itemIndex: number,
|
||||||
): Promise<INodeExecutionData> {
|
): Promise<INodeExecutionData> {
|
||||||
const documentId = this.getNodeParameter('documentId', itemIndex) as string;
|
const documentId = this.getNodeParameter('documentId', itemIndex) as string;
|
||||||
const changelog = this.getNodeParameter('changelog', itemIndex, '') as string;
|
const minor = this.getNodeParameter('minor', itemIndex, false) as boolean;
|
||||||
|
const approverIdsRaw = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
||||||
|
const changelog = this.getNodeParameter('changelog', itemIndex) as string;
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation PublishMajorDocumentVersion($input: PublishMajorDocumentVersionInput!) {
|
mutation PublishDocument($input: PublishDocumentInput!) {
|
||||||
publishMajorDocumentVersion(input: $input) {
|
publishDocument(input: $input) {
|
||||||
document {
|
document {
|
||||||
id
|
id
|
||||||
status
|
status
|
||||||
@@ -81,12 +111,24 @@ export async function execute(
|
|||||||
createdAt
|
createdAt
|
||||||
updatedAt
|
updatedAt
|
||||||
}
|
}
|
||||||
|
approvalQuorum {
|
||||||
|
id
|
||||||
|
status
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const input: Record<string, unknown> = { documentId };
|
const input: Record<string, unknown> = { documentId, minor, changelog };
|
||||||
if (changelog) input.changelog = changelog;
|
if (!minor && approverIdsRaw) {
|
||||||
|
const approverIds = approverIdsRaw
|
||||||
|
.split(',')
|
||||||
|
.map(id => id.trim())
|
||||||
|
.filter(Boolean);
|
||||||
|
if (approverIds.length > 0) input.approverIds = approverIds;
|
||||||
|
}
|
||||||
|
|
||||||
const responseData = await proboApiRequest.call(this, query, { input });
|
const responseData = await proboApiRequest.call(this, query, { input });
|
||||||
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||||
// copyright notice and this permission notice appear in all copies.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
||||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
||||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
||||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
||||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
||||||
import { proboApiRequest } from '../../GenericFunctions';
|
|
||||||
|
|
||||||
export const description: INodeProperties[] = [
|
|
||||||
{
|
|
||||||
displayName: 'Document ID',
|
|
||||||
name: 'documentId',
|
|
||||||
type: 'string',
|
|
||||||
displayOptions: {
|
|
||||||
show: {
|
|
||||||
resource: ['document'],
|
|
||||||
operation: ['publishMinorVersion'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
default: '',
|
|
||||||
description: 'The ID of the document',
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Changelog',
|
|
||||||
name: 'changelog',
|
|
||||||
type: 'string',
|
|
||||||
typeOptions: {
|
|
||||||
rows: 4,
|
|
||||||
},
|
|
||||||
displayOptions: {
|
|
||||||
show: {
|
|
||||||
resource: ['document'],
|
|
||||||
operation: ['publishMinorVersion'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
default: '',
|
|
||||||
description: 'The changelog for this version',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export async function execute(
|
|
||||||
this: IExecuteFunctions,
|
|
||||||
itemIndex: number,
|
|
||||||
): Promise<INodeExecutionData> {
|
|
||||||
const documentId = this.getNodeParameter('documentId', itemIndex) as string;
|
|
||||||
const changelog = this.getNodeParameter('changelog', itemIndex, '') as string;
|
|
||||||
|
|
||||||
const query = `
|
|
||||||
mutation PublishMinorDocumentVersion($input: PublishMinorDocumentVersionInput!) {
|
|
||||||
publishMinorDocumentVersion(input: $input) {
|
|
||||||
document {
|
|
||||||
id
|
|
||||||
status
|
|
||||||
trustCenterVisibility
|
|
||||||
currentPublishedMajor
|
|
||||||
currentPublishedMinor
|
|
||||||
createdAt
|
|
||||||
updatedAt
|
|
||||||
}
|
|
||||||
documentVersion {
|
|
||||||
id
|
|
||||||
title
|
|
||||||
major
|
|
||||||
minor
|
|
||||||
status
|
|
||||||
content
|
|
||||||
changelog
|
|
||||||
classification
|
|
||||||
documentType
|
|
||||||
publishedAt
|
|
||||||
createdAt
|
|
||||||
updatedAt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const input: Record<string, unknown> = { documentId };
|
|
||||||
if (changelog) input.changelog = changelog;
|
|
||||||
|
|
||||||
const responseData = await proboApiRequest.call(this, query, { input });
|
|
||||||
|
|
||||||
return {
|
|
||||||
json: responseData,
|
|
||||||
pairedItem: { item: itemIndex },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||||
// copyright notice and this permission notice appear in all copies.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
||||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
||||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
||||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
||||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
import type { INodeProperties, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
||||||
import { proboApiRequest } from '../../GenericFunctions';
|
|
||||||
|
|
||||||
export const description: INodeProperties[] = [
|
|
||||||
{
|
|
||||||
displayName: 'Document ID',
|
|
||||||
name: 'documentId',
|
|
||||||
type: 'string',
|
|
||||||
displayOptions: {
|
|
||||||
show: {
|
|
||||||
resource: ['document'],
|
|
||||||
operation: ['requestApproval'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
default: '',
|
|
||||||
description: 'The ID of the document',
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Approver IDs',
|
|
||||||
name: 'approverIds',
|
|
||||||
type: 'string',
|
|
||||||
displayOptions: {
|
|
||||||
show: {
|
|
||||||
resource: ['document'],
|
|
||||||
operation: ['requestApproval'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
default: '',
|
|
||||||
description: 'Comma-separated list of approver profile IDs',
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Changelog',
|
|
||||||
name: 'changelog',
|
|
||||||
type: 'string',
|
|
||||||
typeOptions: {
|
|
||||||
rows: 4,
|
|
||||||
},
|
|
||||||
displayOptions: {
|
|
||||||
show: {
|
|
||||||
resource: ['document'],
|
|
||||||
operation: ['requestApproval'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
default: '',
|
|
||||||
description: 'The changelog for this version',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export async function execute(
|
|
||||||
this: IExecuteFunctions,
|
|
||||||
itemIndex: number,
|
|
||||||
): Promise<INodeExecutionData> {
|
|
||||||
const documentId = this.getNodeParameter('documentId', itemIndex) as string;
|
|
||||||
const approverIds = this.getNodeParameter('approverIds', itemIndex) as string;
|
|
||||||
const changelog = this.getNodeParameter('changelog', itemIndex, '') as string;
|
|
||||||
|
|
||||||
const query = `
|
|
||||||
mutation RequestDocumentVersionApproval($input: RequestDocumentVersionApprovalInput!) {
|
|
||||||
requestDocumentVersionApproval(input: $input) {
|
|
||||||
approvalQuorum {
|
|
||||||
id
|
|
||||||
createdAt
|
|
||||||
updatedAt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const input: Record<string, unknown> = {
|
|
||||||
documentId,
|
|
||||||
approverIds: approverIds.split(',').map(id => id.trim()).filter(Boolean),
|
|
||||||
};
|
|
||||||
if (changelog) input.changelog = changelog;
|
|
||||||
|
|
||||||
const responseData = await proboApiRequest.call(this, query, { input });
|
|
||||||
|
|
||||||
return {
|
|
||||||
json: responseData,
|
|
||||||
pairedItem: { item: itemIndex },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -43,6 +43,19 @@ export const description: INodeProperties[] = [
|
|||||||
default: '',
|
default: '',
|
||||||
description: 'Comma-separated list of approver profile IDs',
|
description: 'Comma-separated list of approver profile IDs',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Minor',
|
||||||
|
name: 'minor',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: ['dpia'],
|
||||||
|
operation: ['publish'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: false,
|
||||||
|
description: 'Whether to publish as a minor version. Approvers are ignored when set. The list must already have a published major version.',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export async function execute(
|
export async function execute(
|
||||||
@@ -51,6 +64,7 @@ export async function execute(
|
|||||||
): Promise<INodeExecutionData> {
|
): Promise<INodeExecutionData> {
|
||||||
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
|
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
|
||||||
const approverIds = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
const approverIds = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
||||||
|
const minor = this.getNodeParameter('minor', itemIndex, false) as boolean;
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation PublishDataProtectionImpactAssessmentList($input: PublishDataProtectionImpactAssessmentListInput!) {
|
mutation PublishDataProtectionImpactAssessmentList($input: PublishDataProtectionImpactAssessmentListInput!) {
|
||||||
@@ -83,7 +97,7 @@ export async function execute(
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const input: Record<string, unknown> = { organizationId };
|
const input: Record<string, unknown> = { organizationId, minor };
|
||||||
|
|
||||||
if (approverIds) {
|
if (approverIds) {
|
||||||
input.approverIds = approverIds
|
input.approverIds = approverIds
|
||||||
|
|||||||
@@ -43,6 +43,19 @@ export const description: INodeProperties[] = [
|
|||||||
default: '',
|
default: '',
|
||||||
description: 'Comma-separated list of approver profile IDs',
|
description: 'Comma-separated list of approver profile IDs',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Minor',
|
||||||
|
name: 'minor',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: ['finding'],
|
||||||
|
operation: ['publish'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: false,
|
||||||
|
description: 'Whether to publish as a minor version. Approvers are ignored when set. The list must already have a published major version.',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export async function execute(
|
export async function execute(
|
||||||
@@ -51,6 +64,7 @@ export async function execute(
|
|||||||
): Promise<INodeExecutionData> {
|
): Promise<INodeExecutionData> {
|
||||||
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
|
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
|
||||||
const approverIds = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
const approverIds = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
||||||
|
const minor = this.getNodeParameter('minor', itemIndex, false) as boolean;
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation PublishFindingList($input: PublishFindingListInput!) {
|
mutation PublishFindingList($input: PublishFindingListInput!) {
|
||||||
@@ -83,7 +97,7 @@ export async function execute(
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const input: Record<string, unknown> = { organizationId };
|
const input: Record<string, unknown> = { organizationId, minor };
|
||||||
|
|
||||||
if (approverIds) {
|
if (approverIds) {
|
||||||
input.approverIds = approverIds
|
input.approverIds = approverIds
|
||||||
|
|||||||
@@ -43,6 +43,19 @@ export const description: INodeProperties[] = [
|
|||||||
default: '',
|
default: '',
|
||||||
description: 'Comma-separated list of approver profile IDs',
|
description: 'Comma-separated list of approver profile IDs',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Minor',
|
||||||
|
name: 'minor',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: ['obligation'],
|
||||||
|
operation: ['publish'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: false,
|
||||||
|
description: 'Whether to publish as a minor version. Approvers are ignored when set. The list must already have a published major version.',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export async function execute(
|
export async function execute(
|
||||||
@@ -51,6 +64,7 @@ export async function execute(
|
|||||||
): Promise<INodeExecutionData> {
|
): Promise<INodeExecutionData> {
|
||||||
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
|
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
|
||||||
const approverIds = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
const approverIds = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
||||||
|
const minor = this.getNodeParameter('minor', itemIndex, false) as boolean;
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation PublishObligationList($input: PublishObligationListInput!) {
|
mutation PublishObligationList($input: PublishObligationListInput!) {
|
||||||
@@ -83,7 +97,7 @@ export async function execute(
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const input: Record<string, unknown> = { organizationId };
|
const input: Record<string, unknown> = { organizationId, minor };
|
||||||
|
|
||||||
if (approverIds) {
|
if (approverIds) {
|
||||||
input.approverIds = approverIds
|
input.approverIds = approverIds
|
||||||
|
|||||||
@@ -43,6 +43,19 @@ export const description: INodeProperties[] = [
|
|||||||
default: '',
|
default: '',
|
||||||
description: 'Comma-separated list of approver profile IDs',
|
description: 'Comma-separated list of approver profile IDs',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Minor',
|
||||||
|
name: 'minor',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: ['processingActivity'],
|
||||||
|
operation: ['publish'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: false,
|
||||||
|
description: 'Whether to publish as a minor version. Approvers are ignored when set. The list must already have a published major version.',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export async function execute(
|
export async function execute(
|
||||||
@@ -51,6 +64,7 @@ export async function execute(
|
|||||||
): Promise<INodeExecutionData> {
|
): Promise<INodeExecutionData> {
|
||||||
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
|
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
|
||||||
const approverIds = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
const approverIds = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
||||||
|
const minor = this.getNodeParameter('minor', itemIndex, false) as boolean;
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation PublishProcessingActivityList($input: PublishProcessingActivityListInput!) {
|
mutation PublishProcessingActivityList($input: PublishProcessingActivityListInput!) {
|
||||||
@@ -83,7 +97,7 @@ export async function execute(
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const input: Record<string, unknown> = { organizationId };
|
const input: Record<string, unknown> = { organizationId, minor };
|
||||||
|
|
||||||
if (approverIds) {
|
if (approverIds) {
|
||||||
input.approverIds = approverIds
|
input.approverIds = approverIds
|
||||||
|
|||||||
@@ -43,6 +43,19 @@ export const description: INodeProperties[] = [
|
|||||||
default: '',
|
default: '',
|
||||||
description: 'Comma-separated list of approver profile IDs',
|
description: 'Comma-separated list of approver profile IDs',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Minor',
|
||||||
|
name: 'minor',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: ['risk'],
|
||||||
|
operation: ['publish'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: false,
|
||||||
|
description: 'Whether to publish as a minor version. Approvers are ignored when set. The list must already have a published major version.',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export async function execute(
|
export async function execute(
|
||||||
@@ -51,6 +64,7 @@ export async function execute(
|
|||||||
): Promise<INodeExecutionData> {
|
): Promise<INodeExecutionData> {
|
||||||
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
|
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
|
||||||
const approverIds = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
const approverIds = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
||||||
|
const minor = this.getNodeParameter('minor', itemIndex, false) as boolean;
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation PublishRiskList($input: PublishRiskListInput!) {
|
mutation PublishRiskList($input: PublishRiskListInput!) {
|
||||||
@@ -83,7 +97,7 @@ export async function execute(
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const input: Record<string, unknown> = { organizationId };
|
const input: Record<string, unknown> = { organizationId, minor };
|
||||||
|
|
||||||
if (approverIds) {
|
if (approverIds) {
|
||||||
input.approverIds = approverIds
|
input.approverIds = approverIds
|
||||||
|
|||||||
@@ -43,6 +43,19 @@ export const description: INodeProperties[] = [
|
|||||||
default: '',
|
default: '',
|
||||||
description: 'Comma-separated list of approver profile IDs',
|
description: 'Comma-separated list of approver profile IDs',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Minor',
|
||||||
|
name: 'minor',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: ['statementOfApplicability'],
|
||||||
|
operation: ['publish'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: false,
|
||||||
|
description: 'Whether to publish as a minor version. Approvers are ignored when set. The list must already have a published major version.',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export async function execute(
|
export async function execute(
|
||||||
@@ -51,6 +64,7 @@ export async function execute(
|
|||||||
): Promise<INodeExecutionData> {
|
): Promise<INodeExecutionData> {
|
||||||
const statementOfApplicabilityId = this.getNodeParameter('statementOfApplicabilityId', itemIndex) as string;
|
const statementOfApplicabilityId = this.getNodeParameter('statementOfApplicabilityId', itemIndex) as string;
|
||||||
const approverIds = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
const approverIds = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
||||||
|
const minor = this.getNodeParameter('minor', itemIndex, false) as boolean;
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation PublishStatementOfApplicability($input: PublishStatementOfApplicabilityInput!) {
|
mutation PublishStatementOfApplicability($input: PublishStatementOfApplicabilityInput!) {
|
||||||
@@ -83,7 +97,7 @@ export async function execute(
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const input: Record<string, unknown> = { statementOfApplicabilityId };
|
const input: Record<string, unknown> = { statementOfApplicabilityId, minor };
|
||||||
|
|
||||||
if (approverIds) {
|
if (approverIds) {
|
||||||
input.approverIds = approverIds
|
input.approverIds = approverIds
|
||||||
|
|||||||
@@ -43,6 +43,19 @@ export const description: INodeProperties[] = [
|
|||||||
default: '',
|
default: '',
|
||||||
description: 'Comma-separated list of approver profile IDs',
|
description: 'Comma-separated list of approver profile IDs',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Minor',
|
||||||
|
name: 'minor',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: ['tia'],
|
||||||
|
operation: ['publish'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: false,
|
||||||
|
description: 'Whether to publish as a minor version. Approvers are ignored when set. The list must already have a published major version.',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export async function execute(
|
export async function execute(
|
||||||
@@ -51,6 +64,7 @@ export async function execute(
|
|||||||
): Promise<INodeExecutionData> {
|
): Promise<INodeExecutionData> {
|
||||||
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
|
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
|
||||||
const approverIds = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
const approverIds = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
||||||
|
const minor = this.getNodeParameter('minor', itemIndex, false) as boolean;
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation PublishTransferImpactAssessmentList($input: PublishTransferImpactAssessmentListInput!) {
|
mutation PublishTransferImpactAssessmentList($input: PublishTransferImpactAssessmentListInput!) {
|
||||||
@@ -83,7 +97,7 @@ export async function execute(
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const input: Record<string, unknown> = { organizationId };
|
const input: Record<string, unknown> = { organizationId, minor };
|
||||||
|
|
||||||
if (approverIds) {
|
if (approverIds) {
|
||||||
input.approverIds = approverIds
|
input.approverIds = approverIds
|
||||||
|
|||||||
@@ -43,6 +43,19 @@ export const description: INodeProperties[] = [
|
|||||||
default: '',
|
default: '',
|
||||||
description: 'Comma-separated list of approver profile IDs',
|
description: 'Comma-separated list of approver profile IDs',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Minor',
|
||||||
|
name: 'minor',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: ['vendor'],
|
||||||
|
operation: ['publish'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: false,
|
||||||
|
description: 'Whether to publish as a minor version. Approvers are ignored when set. The list must already have a published major version.',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export async function execute(
|
export async function execute(
|
||||||
@@ -51,6 +64,7 @@ export async function execute(
|
|||||||
): Promise<INodeExecutionData> {
|
): Promise<INodeExecutionData> {
|
||||||
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
|
const organizationId = this.getNodeParameter('organizationId', itemIndex) as string;
|
||||||
const approverIds = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
const approverIds = this.getNodeParameter('approverIds', itemIndex, '') as string;
|
||||||
|
const minor = this.getNodeParameter('minor', itemIndex, false) as boolean;
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation PublishVendorList($input: PublishVendorListInput!) {
|
mutation PublishVendorList($input: PublishVendorListInput!) {
|
||||||
@@ -83,7 +97,7 @@ export async function execute(
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const input: Record<string, unknown> = { organizationId };
|
const input: Record<string, unknown> = { organizationId, minor };
|
||||||
|
|
||||||
if (approverIds) {
|
if (approverIds) {
|
||||||
input.approverIds = approverIds
|
input.approverIds = approverIds
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
var (
|
var (
|
||||||
flagOrg string
|
flagOrg string
|
||||||
flagApprover []string
|
flagApprover []string
|
||||||
|
flagMinor bool
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@@ -108,6 +109,7 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"organizationId": flagOrg,
|
"organizationId": flagOrg,
|
||||||
|
"minor": flagMinor,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(flagApprover) > 0 {
|
if len(flagApprover) > 0 {
|
||||||
@@ -141,7 +143,8 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().StringVar(&flagOrg, "org", "", "Organization ID")
|
cmd.Flags().StringVar(&flagOrg, "org", "", "Organization ID")
|
||||||
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated)")
|
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated; ignored with --minor)")
|
||||||
|
cmd.Flags().BoolVar(&flagMinor, "minor", false, "Publish as a minor version (no approval flow)")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
var (
|
var (
|
||||||
flagOrg string
|
flagOrg string
|
||||||
flagApprover []string
|
flagApprover []string
|
||||||
|
flagMinor bool
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@@ -108,6 +109,7 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"organizationId": flagOrg,
|
"organizationId": flagOrg,
|
||||||
|
"minor": flagMinor,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(flagApprover) > 0 {
|
if len(flagApprover) > 0 {
|
||||||
@@ -141,7 +143,8 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().StringVar(&flagOrg, "org", "", "Organization ID")
|
cmd.Flags().StringVar(&flagOrg, "org", "", "Organization ID")
|
||||||
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated)")
|
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated; ignored with --minor)")
|
||||||
|
cmd.Flags().BoolVar(&flagMinor, "minor", false, "Publish as a minor version (no approval flow)")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,8 +25,7 @@ import (
|
|||||||
listapprovaldecisions "go.probo.inc/probo/pkg/cmd/document/list-approval-decisions"
|
listapprovaldecisions "go.probo.inc/probo/pkg/cmd/document/list-approval-decisions"
|
||||||
listapprovalquorums "go.probo.inc/probo/pkg/cmd/document/list-approval-quorums"
|
listapprovalquorums "go.probo.inc/probo/pkg/cmd/document/list-approval-quorums"
|
||||||
listversions "go.probo.inc/probo/pkg/cmd/document/list-versions"
|
listversions "go.probo.inc/probo/pkg/cmd/document/list-versions"
|
||||||
publishmajor "go.probo.inc/probo/pkg/cmd/document/publish-major"
|
"go.probo.inc/probo/pkg/cmd/document/publish"
|
||||||
publishminor "go.probo.inc/probo/pkg/cmd/document/publish-minor"
|
|
||||||
"go.probo.inc/probo/pkg/cmd/document/unarchive"
|
"go.probo.inc/probo/pkg/cmd/document/unarchive"
|
||||||
"go.probo.inc/probo/pkg/cmd/document/update"
|
"go.probo.inc/probo/pkg/cmd/document/update"
|
||||||
"go.probo.inc/probo/pkg/cmd/document/view"
|
"go.probo.inc/probo/pkg/cmd/document/view"
|
||||||
@@ -51,8 +50,7 @@ func NewCmdDocument(f *cmdutil.Factory) *cobra.Command {
|
|||||||
cmd.AddCommand(listversions.NewCmdListVersions(f))
|
cmd.AddCommand(listversions.NewCmdListVersions(f))
|
||||||
cmd.AddCommand(viewversion.NewCmdViewVersion(f))
|
cmd.AddCommand(viewversion.NewCmdViewVersion(f))
|
||||||
cmd.AddCommand(deletedraft.NewCmdDeleteDraft(f))
|
cmd.AddCommand(deletedraft.NewCmdDeleteDraft(f))
|
||||||
cmd.AddCommand(publishmajor.NewCmdPublishMajor(f))
|
cmd.AddCommand(publish.NewCmdPublish(f))
|
||||||
cmd.AddCommand(publishminor.NewCmdPublishMinor(f))
|
|
||||||
cmd.AddCommand(listapprovalquorums.NewCmdListApprovalQuorums(f))
|
cmd.AddCommand(listapprovalquorums.NewCmdListApprovalQuorums(f))
|
||||||
cmd.AddCommand(viewapprovalquorum.NewCmdViewApprovalQuorum(f))
|
cmd.AddCommand(viewapprovalquorum.NewCmdViewApprovalQuorum(f))
|
||||||
cmd.AddCommand(listapprovaldecisions.NewCmdListApprovalDecisions(f))
|
cmd.AddCommand(listapprovaldecisions.NewCmdListApprovalDecisions(f))
|
||||||
|
|||||||
@@ -1,115 +0,0 @@
|
|||||||
// Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||||
// copyright notice and this permission notice appear in all copies.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
||||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
||||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
||||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
||||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
package publishmajor
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
"go.probo.inc/probo/pkg/cli/api"
|
|
||||||
"go.probo.inc/probo/pkg/cmd/cmdutil"
|
|
||||||
)
|
|
||||||
|
|
||||||
const publishMajorMutation = `
|
|
||||||
mutation($input: PublishMajorDocumentVersionInput!) {
|
|
||||||
publishMajorDocumentVersion(input: $input) {
|
|
||||||
documentVersion {
|
|
||||||
id
|
|
||||||
title
|
|
||||||
major
|
|
||||||
minor
|
|
||||||
status
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
type publishResponse struct {
|
|
||||||
PublishMajorDocumentVersion struct {
|
|
||||||
DocumentVersion struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Title string `json:"title"`
|
|
||||||
Major int `json:"major"`
|
|
||||||
Minor int `json:"minor"`
|
|
||||||
Status string `json:"status"`
|
|
||||||
} `json:"documentVersion"`
|
|
||||||
} `json:"publishMajorDocumentVersion"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewCmdPublishMajor(f *cmdutil.Factory) *cobra.Command {
|
|
||||||
var flagChangelog string
|
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
|
||||||
Use: "publish-major <document-id>",
|
|
||||||
Short: "Publish a major version of a document",
|
|
||||||
Args: cobra.ExactArgs(1),
|
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
|
||||||
cfg, err := f.Config()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
host, hc, err := cfg.DefaultHost()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
client := api.NewClient(
|
|
||||||
host,
|
|
||||||
hc.Token,
|
|
||||||
"/api/console/v1/graphql",
|
|
||||||
cfg.HTTPTimeoutDuration(),
|
|
||||||
)
|
|
||||||
|
|
||||||
input := map[string]any{
|
|
||||||
"documentId": args[0],
|
|
||||||
}
|
|
||||||
|
|
||||||
if flagChangelog != "" {
|
|
||||||
input["changelog"] = flagChangelog
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := client.Do(
|
|
||||||
publishMajorMutation,
|
|
||||||
map[string]any{"input": input},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var resp publishResponse
|
|
||||||
if err := json.Unmarshal(data, &resp); err != nil {
|
|
||||||
return fmt.Errorf("cannot parse response: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v := resp.PublishMajorDocumentVersion.DocumentVersion
|
|
||||||
_, _ = fmt.Fprintf(
|
|
||||||
f.IOStreams.Out,
|
|
||||||
"Published major version %s (%s v%d.%d)\n",
|
|
||||||
v.ID,
|
|
||||||
v.Title,
|
|
||||||
v.Major,
|
|
||||||
v.Minor,
|
|
||||||
)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Flags().StringVar(&flagChangelog, "changelog", "", "Changelog for this version")
|
|
||||||
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
// PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
package publishminor
|
package publish
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@@ -23,9 +23,9 @@ import (
|
|||||||
"go.probo.inc/probo/pkg/cmd/cmdutil"
|
"go.probo.inc/probo/pkg/cmd/cmdutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
const publishMinorMutation = `
|
const publishMutation = `
|
||||||
mutation($input: PublishMinorDocumentVersionInput!) {
|
mutation($input: PublishDocumentInput!) {
|
||||||
publishMinorDocumentVersion(input: $input) {
|
publishDocument(input: $input) {
|
||||||
documentVersion {
|
documentVersion {
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
@@ -33,12 +33,16 @@ mutation($input: PublishMinorDocumentVersionInput!) {
|
|||||||
minor
|
minor
|
||||||
status
|
status
|
||||||
}
|
}
|
||||||
|
approvalQuorum {
|
||||||
|
id
|
||||||
|
status
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
type publishResponse struct {
|
type publishResponse struct {
|
||||||
PublishMinorDocumentVersion struct {
|
PublishDocument struct {
|
||||||
DocumentVersion struct {
|
DocumentVersion struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
@@ -46,17 +50,35 @@ type publishResponse struct {
|
|||||||
Minor int `json:"minor"`
|
Minor int `json:"minor"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
} `json:"documentVersion"`
|
} `json:"documentVersion"`
|
||||||
} `json:"publishMinorDocumentVersion"`
|
ApprovalQuorum *struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
} `json:"approvalQuorum"`
|
||||||
|
} `json:"publishDocument"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCmdPublishMinor(f *cmdutil.Factory) *cobra.Command {
|
func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
||||||
var flagChangelog string
|
var (
|
||||||
|
flagMinor bool
|
||||||
|
flagApprover []string
|
||||||
|
flagChangelog string
|
||||||
|
)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "publish-minor <document-id>",
|
Use: "publish <document-id>",
|
||||||
Short: "Publish a minor version of a document",
|
Short: "Publish a document",
|
||||||
Args: cobra.ExactArgs(1),
|
Long: `Publish the latest draft of a document.
|
||||||
|
|
||||||
|
By default, the draft is published as a new major version. Pass --minor to
|
||||||
|
publish as a minor version (the document must already have a major version).
|
||||||
|
When --approver is set (one or more profile IDs), an approval is requested
|
||||||
|
instead of publishing immediately. Approvers are ignored with --minor.`,
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
if flagChangelog == "" {
|
||||||
|
return fmt.Errorf("--changelog is required")
|
||||||
|
}
|
||||||
|
|
||||||
cfg, err := f.Config()
|
cfg, err := f.Config()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -76,14 +98,16 @@ func NewCmdPublishMinor(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"documentId": args[0],
|
"documentId": args[0],
|
||||||
|
"minor": flagMinor,
|
||||||
|
"changelog": flagChangelog,
|
||||||
}
|
}
|
||||||
|
|
||||||
if flagChangelog != "" {
|
if len(flagApprover) > 0 {
|
||||||
input["changelog"] = flagChangelog
|
input["approverIds"] = flagApprover
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := client.Do(
|
data, err := client.Do(
|
||||||
publishMinorMutation,
|
publishMutation,
|
||||||
map[string]any{"input": input},
|
map[string]any{"input": input},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -95,10 +119,23 @@ func NewCmdPublishMinor(f *cmdutil.Factory) *cobra.Command {
|
|||||||
return fmt.Errorf("cannot parse response: %w", err)
|
return fmt.Errorf("cannot parse response: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
v := resp.PublishMinorDocumentVersion.DocumentVersion
|
v := resp.PublishDocument.DocumentVersion
|
||||||
|
if resp.PublishDocument.ApprovalQuorum != nil {
|
||||||
|
_, _ = fmt.Fprintf(
|
||||||
|
f.IOStreams.Out,
|
||||||
|
"Requested approval for %s (%s v%d.%d, status %s)\n",
|
||||||
|
v.ID,
|
||||||
|
v.Title,
|
||||||
|
v.Major,
|
||||||
|
v.Minor,
|
||||||
|
v.Status,
|
||||||
|
)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
_, _ = fmt.Fprintf(
|
_, _ = fmt.Fprintf(
|
||||||
f.IOStreams.Out,
|
f.IOStreams.Out,
|
||||||
"Published minor version %s (%s v%d.%d)\n",
|
"Published %s (%s v%d.%d)\n",
|
||||||
v.ID,
|
v.ID,
|
||||||
v.Title,
|
v.Title,
|
||||||
v.Major,
|
v.Major,
|
||||||
@@ -109,7 +146,9 @@ func NewCmdPublishMinor(f *cmdutil.Factory) *cobra.Command {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().StringVar(&flagChangelog, "changelog", "", "Changelog for this version")
|
cmd.Flags().BoolVar(&flagMinor, "minor", false, "Publish as a minor version (no approval flow)")
|
||||||
|
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated; ignored with --minor)")
|
||||||
|
cmd.Flags().StringVar(&flagChangelog, "changelog", "", "Changelog for this version (required)")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@@ -71,6 +71,7 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
var (
|
var (
|
||||||
flagOrg string
|
flagOrg string
|
||||||
flagApprover []string
|
flagApprover []string
|
||||||
|
flagMinor bool
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@@ -108,6 +109,7 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"organizationId": flagOrg,
|
"organizationId": flagOrg,
|
||||||
|
"minor": flagMinor,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(flagApprover) > 0 {
|
if len(flagApprover) > 0 {
|
||||||
@@ -142,7 +144,8 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().StringVar(&flagOrg, "org", "", "Organization ID")
|
cmd.Flags().StringVar(&flagOrg, "org", "", "Organization ID")
|
||||||
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated)")
|
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated; ignored with --minor)")
|
||||||
|
cmd.Flags().BoolVar(&flagMinor, "minor", false, "Publish as a minor version (no approval flow)")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
var (
|
var (
|
||||||
flagOrg string
|
flagOrg string
|
||||||
flagApprover []string
|
flagApprover []string
|
||||||
|
flagMinor bool
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@@ -108,6 +109,7 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"organizationId": flagOrg,
|
"organizationId": flagOrg,
|
||||||
|
"minor": flagMinor,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(flagApprover) > 0 {
|
if len(flagApprover) > 0 {
|
||||||
@@ -141,7 +143,8 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().StringVar(&flagOrg, "org", "", "Organization ID")
|
cmd.Flags().StringVar(&flagOrg, "org", "", "Organization ID")
|
||||||
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated)")
|
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated; ignored with --minor)")
|
||||||
|
cmd.Flags().BoolVar(&flagMinor, "minor", false, "Publish as a minor version (no approval flow)")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
var (
|
var (
|
||||||
flagOrg string
|
flagOrg string
|
||||||
flagApprover []string
|
flagApprover []string
|
||||||
|
flagMinor bool
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@@ -108,6 +109,7 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"organizationId": flagOrg,
|
"organizationId": flagOrg,
|
||||||
|
"minor": flagMinor,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(flagApprover) > 0 {
|
if len(flagApprover) > 0 {
|
||||||
@@ -141,7 +143,8 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().StringVar(&flagOrg, "org", "", "Organization ID")
|
cmd.Flags().StringVar(&flagOrg, "org", "", "Organization ID")
|
||||||
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated)")
|
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated; ignored with --minor)")
|
||||||
|
cmd.Flags().BoolVar(&flagMinor, "minor", false, "Publish as a minor version (no approval flow)")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
var (
|
var (
|
||||||
flagOrg string
|
flagOrg string
|
||||||
flagApprover []string
|
flagApprover []string
|
||||||
|
flagMinor bool
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@@ -108,6 +109,7 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"organizationId": flagOrg,
|
"organizationId": flagOrg,
|
||||||
|
"minor": flagMinor,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(flagApprover) > 0 {
|
if len(flagApprover) > 0 {
|
||||||
@@ -142,7 +144,8 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().StringVar(&flagOrg, "org", "", "Organization ID")
|
cmd.Flags().StringVar(&flagOrg, "org", "", "Organization ID")
|
||||||
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated)")
|
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated; ignored with --minor)")
|
||||||
|
cmd.Flags().BoolVar(&flagMinor, "minor", false, "Publish as a minor version (no approval flow)")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
var (
|
var (
|
||||||
flagOrg string
|
flagOrg string
|
||||||
flagApprover []string
|
flagApprover []string
|
||||||
|
flagMinor bool
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@@ -109,6 +110,7 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"organizationId": flagOrg,
|
"organizationId": flagOrg,
|
||||||
|
"minor": flagMinor,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(flagApprover) > 0 {
|
if len(flagApprover) > 0 {
|
||||||
@@ -142,7 +144,8 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().StringVar(&flagOrg, "org", "", "Organization ID")
|
cmd.Flags().StringVar(&flagOrg, "org", "", "Organization ID")
|
||||||
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated)")
|
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated; ignored with --minor)")
|
||||||
|
cmd.Flags().BoolVar(&flagMinor, "minor", false, "Publish as a minor version (no approval flow)")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,10 @@ type publishResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
||||||
var flagApprover []string
|
var (
|
||||||
|
flagApprover []string
|
||||||
|
flagMinor bool
|
||||||
|
)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "publish <soa-id>",
|
Use: "publish <soa-id>",
|
||||||
@@ -99,6 +102,7 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"statementOfApplicabilityId": args[0],
|
"statementOfApplicabilityId": args[0],
|
||||||
|
"minor": flagMinor,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(flagApprover) > 0 {
|
if len(flagApprover) > 0 {
|
||||||
@@ -131,7 +135,8 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated)")
|
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated; ignored with --minor)")
|
||||||
|
cmd.Flags().BoolVar(&flagMinor, "minor", false, "Publish as a minor version (no approval flow)")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
var (
|
var (
|
||||||
flagOrg string
|
flagOrg string
|
||||||
flagApprover []string
|
flagApprover []string
|
||||||
|
flagMinor bool
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@@ -108,6 +109,7 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"organizationId": flagOrg,
|
"organizationId": flagOrg,
|
||||||
|
"minor": flagMinor,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(flagApprover) > 0 {
|
if len(flagApprover) > 0 {
|
||||||
@@ -142,7 +144,8 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().StringVar(&flagOrg, "org", "", "Organization ID")
|
cmd.Flags().StringVar(&flagOrg, "org", "", "Organization ID")
|
||||||
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated)")
|
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated; ignored with --minor)")
|
||||||
|
cmd.Flags().BoolVar(&flagMinor, "minor", false, "Publish as a minor version (no approval flow)")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
var (
|
var (
|
||||||
flagOrg string
|
flagOrg string
|
||||||
flagApprover []string
|
flagApprover []string
|
||||||
|
flagMinor bool
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@@ -109,6 +110,7 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"organizationId": flagOrg,
|
"organizationId": flagOrg,
|
||||||
|
"minor": flagMinor,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(flagApprover) > 0 {
|
if len(flagApprover) > 0 {
|
||||||
@@ -142,7 +144,8 @@ func NewCmdPublish(f *cmdutil.Factory) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().StringVar(&flagOrg, "org", "", "Organization ID")
|
cmd.Flags().StringVar(&flagOrg, "org", "", "Organization ID")
|
||||||
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated)")
|
cmd.Flags().StringArrayVar(&flagApprover, "approver", nil, "Approver profile ID (can be repeated; ignored with --minor)")
|
||||||
|
cmd.Flags().BoolVar(&flagMinor, "minor", false, "Publish as a minor version (no approval flow)")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import (
|
|||||||
"go.probo.inc/probo/pkg/mail"
|
"go.probo.inc/probo/pkg/mail"
|
||||||
"go.probo.inc/probo/pkg/page"
|
"go.probo.inc/probo/pkg/page"
|
||||||
"go.probo.inc/probo/pkg/statelesstoken"
|
"go.probo.inc/probo/pkg/statelesstoken"
|
||||||
"go.probo.inc/probo/pkg/validator"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@@ -49,12 +48,6 @@ type (
|
|||||||
|
|
||||||
ErrApprovalDecisionAlreadyMade struct{}
|
ErrApprovalDecisionAlreadyMade struct{}
|
||||||
|
|
||||||
RequestApprovalRequest struct {
|
|
||||||
DocumentID gid.GID
|
|
||||||
ApproverIDs []gid.GID
|
|
||||||
Changelog *string
|
|
||||||
}
|
|
||||||
|
|
||||||
ApproveDocumentVersionRequest struct {
|
ApproveDocumentVersionRequest struct {
|
||||||
DocumentVersionID gid.GID
|
DocumentVersionID gid.GID
|
||||||
IdentityID gid.GID
|
IdentityID gid.GID
|
||||||
@@ -79,85 +72,6 @@ func (e ErrApprovalDecisionAlreadyMade) Error() string {
|
|||||||
return "approval decision has already been made"
|
return "approval decision has already been made"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (req *RequestApprovalRequest) Validate() error {
|
|
||||||
v := validator.New()
|
|
||||||
|
|
||||||
v.Check(req.DocumentID, "document_id", validator.Required(), validator.GID(coredata.DocumentEntityType))
|
|
||||||
v.Check(len(req.ApproverIDs), "approver_ids", validator.Min(1), validator.Max(100))
|
|
||||||
v.Check(req.ApproverIDs, "approver_ids", validator.NoDuplicates())
|
|
||||||
v.CheckEach(req.ApproverIDs, "approver_ids", func(index int, item any) {
|
|
||||||
v.Check(item, fmt.Sprintf("approver_ids[%d]", index), validator.GID(coredata.MembershipProfileEntityType))
|
|
||||||
})
|
|
||||||
v.Check(req.Changelog, "changelog", validator.Required(), validator.SafeText(5000))
|
|
||||||
|
|
||||||
return v.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *DocumentApprovalService) RequestApproval(
|
|
||||||
ctx context.Context,
|
|
||||||
req RequestApprovalRequest,
|
|
||||||
) (*coredata.DocumentVersionApprovalQuorum, error) {
|
|
||||||
if err := req.Validate(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var quorum *coredata.DocumentVersionApprovalQuorum
|
|
||||||
|
|
||||||
err := s.svc.pg.WithTx(
|
|
||||||
ctx,
|
|
||||||
func(ctx context.Context, tx pg.Tx) error {
|
|
||||||
profiles := &coredata.MembershipProfiles{}
|
|
||||||
if err := profiles.LoadByIDs(ctx, tx, s.svc.scope, req.ApproverIDs); err != nil {
|
|
||||||
return fmt.Errorf("cannot load approver profiles: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
now := time.Now()
|
|
||||||
for _, p := range *profiles {
|
|
||||||
if p.ContractEndDate != nil && p.ContractEndDate.Before(now) {
|
|
||||||
return &ErrProfileContractEnded{ProfileID: p.ID}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document := &coredata.Document{}
|
|
||||||
if err := document.LoadByID(ctx, tx, s.svc.scope, req.DocumentID); err != nil {
|
|
||||||
return fmt.Errorf("cannot load document: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if document.ArchivedAt != nil {
|
|
||||||
return &ErrDocumentArchived{}
|
|
||||||
}
|
|
||||||
|
|
||||||
documentVersion, err := s.loadLatestVersion(ctx, tx, req.DocumentID)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot load latest version: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if documentVersion.Status != coredata.DocumentVersionStatusDraft {
|
|
||||||
return &ErrDocumentVersionNotDraft{}
|
|
||||||
}
|
|
||||||
|
|
||||||
q, err := s.RequestApprovalInTx(ctx, tx, document, documentVersion, req.ApproverIDs, req.Changelog)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
quorum = q
|
|
||||||
|
|
||||||
defaultApprovers := &coredata.DocumentDefaultApprovers{}
|
|
||||||
if err := defaultApprovers.MergeByDocumentID(ctx, tx, s.svc.scope, req.DocumentID, document.OrganizationID, req.ApproverIDs); err != nil {
|
|
||||||
return fmt.Errorf("cannot update default approvers: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return quorum, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *DocumentApprovalService) RequestApprovalInTx(
|
func (s *DocumentApprovalService) RequestApprovalInTx(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
tx pg.Tx,
|
tx pg.Tx,
|
||||||
@@ -219,7 +133,13 @@ func (s *DocumentApprovalService) RequestApprovalInTx(
|
|||||||
return quorum, nil
|
return quorum, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DocumentApprovalService) BulkPublishMajorVersions(
|
// BulkPublishVersions publishes (or requests approval for) the latest draft of
|
||||||
|
// each document. When req.Minor is true each draft is published as a minor
|
||||||
|
// bump and approvers are not consulted. When req.Minor is false, each
|
||||||
|
// document's saved default approvers are honoured: if the document has any,
|
||||||
|
// an approval is requested for it; otherwise it is published as a major
|
||||||
|
// bump. Documents with no draft (or already pending approval) are skipped.
|
||||||
|
func (s *DocumentApprovalService) BulkPublishVersions(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req BulkPublishVersionsRequest,
|
req BulkPublishVersionsRequest,
|
||||||
) ([]*coredata.DocumentVersion, []*coredata.Document, error) {
|
) ([]*coredata.DocumentVersion, []*coredata.Document, error) {
|
||||||
@@ -235,7 +155,6 @@ func (s *DocumentApprovalService) BulkPublishMajorVersions(
|
|||||||
return fmt.Errorf("cannot load latest version for %q: %w", documentID, err)
|
return fmt.Errorf("cannot load latest version for %q: %w", documentID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip documents already pending approval.
|
|
||||||
if dv.Status == coredata.DocumentVersionStatusPendingApproval {
|
if dv.Status == coredata.DocumentVersionStatusPendingApproval {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -249,30 +168,47 @@ func (s *DocumentApprovalService) BulkPublishMajorVersions(
|
|||||||
return &ErrDocumentArchived{}
|
return &ErrDocumentArchived{}
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultApprovers := &coredata.DocumentDefaultApprovers{}
|
// Treat minor on an already-published version as a no-op so the
|
||||||
if err := defaultApprovers.LoadByDocumentID(ctx, tx, s.svc.scope, documentID); err != nil {
|
// operation is idempotent: the doc is included in the result
|
||||||
return fmt.Errorf("cannot load default approvers for %q: %w", documentID, err)
|
// without modification.
|
||||||
|
if req.Minor && dv.Status == coredata.DocumentVersionStatusPublished {
|
||||||
|
publishedVersions = append(publishedVersions, dv)
|
||||||
|
updatedDocuments = append(updatedDocuments, document)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if dv.Status != coredata.DocumentVersionStatusDraft {
|
if dv.Status != coredata.DocumentVersionStatusDraft {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(*defaultApprovers) > 0 {
|
if req.Minor {
|
||||||
approverIDs := make([]gid.GID, len(*defaultApprovers))
|
|
||||||
for i, a := range *defaultApprovers {
|
|
||||||
approverIDs[i] = a.ApproverProfileID
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := s.RequestApprovalInTx(ctx, tx, document, dv, approverIDs, &req.Changelog); err != nil {
|
|
||||||
return fmt.Errorf("cannot request approval for %q: %w", documentID, err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var err error
|
var err error
|
||||||
document, dv, err = s.svc.Documents.publishMajorVersionInTx(ctx, tx, documentID, &req.Changelog, true)
|
document, dv, err = s.svc.Documents.publishMinorVersionInTx(ctx, tx, documentID, &req.Changelog, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot publish document %q: %w", documentID, err)
|
return fmt.Errorf("cannot publish document %q: %w", documentID, err)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
defaultApprovers := &coredata.DocumentDefaultApprovers{}
|
||||||
|
if err := defaultApprovers.LoadByDocumentID(ctx, tx, s.svc.scope, documentID); err != nil {
|
||||||
|
return fmt.Errorf("cannot load default approvers for %q: %w", documentID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(*defaultApprovers) > 0 {
|
||||||
|
approverIDs := make([]gid.GID, len(*defaultApprovers))
|
||||||
|
for i, a := range *defaultApprovers {
|
||||||
|
approverIDs[i] = a.ApproverProfileID
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := s.RequestApprovalInTx(ctx, tx, document, dv, approverIDs, &req.Changelog); err != nil {
|
||||||
|
return fmt.Errorf("cannot request approval for %q: %w", documentID, err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var err error
|
||||||
|
document, dv, err = s.svc.Documents.publishMajorVersionInTx(ctx, tx, documentID, &req.Changelog, true)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot publish document %q: %w", documentID, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
publishedVersions = append(publishedVersions, dv)
|
publishedVersions = append(publishedVersions, dv)
|
||||||
|
|||||||
@@ -75,6 +75,9 @@ type (
|
|||||||
ErrDocumentArchived struct {
|
ErrDocumentArchived struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrCannotPublishMinorWithoutMajor struct {
|
||||||
|
}
|
||||||
|
|
||||||
ErrDocumentDraftNotDeletable struct {
|
ErrDocumentDraftNotDeletable struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,8 +129,22 @@ type (
|
|||||||
|
|
||||||
BulkPublishVersionsRequest struct {
|
BulkPublishVersionsRequest struct {
|
||||||
DocumentIDs []gid.GID
|
DocumentIDs []gid.GID
|
||||||
|
Minor bool
|
||||||
Changelog string
|
Changelog string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PublishDocumentRequest struct {
|
||||||
|
DocumentID gid.GID
|
||||||
|
Minor bool
|
||||||
|
ApproverIDs []gid.GID
|
||||||
|
Changelog string
|
||||||
|
}
|
||||||
|
|
||||||
|
PublishDocumentResult struct {
|
||||||
|
Document *coredata.Document
|
||||||
|
Version *coredata.DocumentVersion
|
||||||
|
Quorum *coredata.DocumentVersionApprovalQuorum
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -159,6 +176,20 @@ func (cdr *CreateDocumentRequest) Validate() error {
|
|||||||
return v.Error()
|
return v.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (req *PublishDocumentRequest) Validate() error {
|
||||||
|
v := validator.New()
|
||||||
|
|
||||||
|
v.Check(req.DocumentID, "document_id", validator.Required(), validator.GID(coredata.DocumentEntityType))
|
||||||
|
v.Check(len(req.ApproverIDs), "approver_ids", validator.Max(100))
|
||||||
|
v.Check(req.ApproverIDs, "approver_ids", validator.NoDuplicates())
|
||||||
|
v.CheckEach(req.ApproverIDs, "approver_ids", func(index int, item any) {
|
||||||
|
v.Check(item, fmt.Sprintf("approver_ids[%d]", index), validator.GID(coredata.MembershipProfileEntityType))
|
||||||
|
})
|
||||||
|
v.Check(req.Changelog, "changelog", validator.Required(), validator.SafeText(5000))
|
||||||
|
|
||||||
|
return v.Error()
|
||||||
|
}
|
||||||
|
|
||||||
func (udr *UpdateDocumentRequest) Validate() error {
|
func (udr *UpdateDocumentRequest) Validate() error {
|
||||||
v := validator.New()
|
v := validator.New()
|
||||||
|
|
||||||
@@ -219,6 +250,10 @@ func (e ErrDocumentArchived) Error() string {
|
|||||||
return "cannot modify an archived document"
|
return "cannot modify an archived document"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e ErrCannotPublishMinorWithoutMajor) Error() string {
|
||||||
|
return "cannot publish a minor version before a major version exists"
|
||||||
|
}
|
||||||
|
|
||||||
func (e ErrDocumentDraftNotDeletable) Error() string {
|
func (e ErrDocumentDraftNotDeletable) Error() string {
|
||||||
return "latest version is not a deletable draft"
|
return "latest version is not a deletable draft"
|
||||||
}
|
}
|
||||||
@@ -506,123 +541,105 @@ func (s DocumentService) generateChangelog(
|
|||||||
return &text, nil
|
return &text, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DocumentService) BulkPublishMinorVersions(
|
// PublishVersion is the single entry point for publishing a document
|
||||||
|
// version. The behaviour depends on req.Minor and req.ApproverIDs:
|
||||||
|
// - Minor=true: publish the existing draft as a minor bump (currentMajor.
|
||||||
|
// currentMinor+1). ApproverIDs are ignored. Errors with
|
||||||
|
// ErrCannotPublishMinorWithoutMajor when the document has never been
|
||||||
|
// published.
|
||||||
|
// - Minor=false with ApproverIDs: open an approval quorum on the draft as
|
||||||
|
// a pending major bump (currentMajor+1.0). Result.Quorum is set.
|
||||||
|
// - Minor=false without ApproverIDs: publish the draft immediately as a
|
||||||
|
// major bump (currentMajor+1.0).
|
||||||
|
func (s *DocumentService) PublishVersion(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req BulkPublishVersionsRequest,
|
req PublishDocumentRequest,
|
||||||
) ([]*coredata.DocumentVersion, []*coredata.Document, error) {
|
) (*PublishDocumentResult, error) {
|
||||||
var publishedVersions []*coredata.DocumentVersion
|
if err := req.Validate(); err != nil {
|
||||||
var updatedDocuments []*coredata.Document
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result := &PublishDocumentResult{}
|
||||||
|
|
||||||
err := s.svc.pg.WithTx(
|
err := s.svc.pg.WithTx(
|
||||||
ctx,
|
ctx,
|
||||||
func(ctx context.Context, tx pg.Tx) error {
|
func(ctx context.Context, tx pg.Tx) error {
|
||||||
for _, documentID := range req.DocumentIDs {
|
dv := &coredata.DocumentVersion{}
|
||||||
dv := &coredata.DocumentVersion{}
|
if err := dv.LoadLatestVersion(ctx, tx, s.svc.scope, req.DocumentID); err != nil {
|
||||||
if err := dv.LoadLatestVersion(ctx, tx, s.svc.scope, documentID); err != nil {
|
return fmt.Errorf("cannot load latest version: %w", err)
|
||||||
return fmt.Errorf("cannot load latest version for %q: %w", documentID, err)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Skip documents already pending approval.
|
if dv.Status == coredata.DocumentVersionStatusPendingApproval {
|
||||||
if dv.Status == coredata.DocumentVersionStatusPendingApproval {
|
return &ErrDocumentVersionPendingApproval{}
|
||||||
continue
|
}
|
||||||
}
|
|
||||||
|
|
||||||
document, version, err := s.publishMinorVersionInTx(ctx, tx, documentID, &req.Changelog, true)
|
if req.Minor {
|
||||||
|
document, version, err := s.publishMinorVersionInTx(ctx, tx, req.DocumentID, &req.Changelog, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot publish document %q: %w", documentID, err)
|
return fmt.Errorf("cannot publish minor version: %w", err)
|
||||||
}
|
}
|
||||||
|
result.Document = document
|
||||||
publishedVersions = append(publishedVersions, version)
|
result.Version = version
|
||||||
updatedDocuments = append(updatedDocuments, document)
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
if len(req.ApproverIDs) == 0 {
|
||||||
},
|
document, version, err := s.publishMajorVersionInTx(ctx, tx, req.DocumentID, &req.Changelog, false)
|
||||||
)
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot publish major version: %w", err)
|
||||||
if err != nil {
|
}
|
||||||
return nil, nil, err
|
result.Document = document
|
||||||
}
|
result.Version = version
|
||||||
|
return nil
|
||||||
return publishedVersions, updatedDocuments, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *DocumentService) PublishMajorVersion(
|
|
||||||
ctx context.Context,
|
|
||||||
documentID gid.GID,
|
|
||||||
publishedBy gid.GID,
|
|
||||||
changelog *string,
|
|
||||||
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
|
||||||
var document *coredata.Document
|
|
||||||
var documentVersion *coredata.DocumentVersion
|
|
||||||
|
|
||||||
err := s.svc.pg.WithTx(
|
|
||||||
ctx,
|
|
||||||
func(ctx context.Context, tx pg.Tx) error {
|
|
||||||
dv := &coredata.DocumentVersion{}
|
|
||||||
if err := dv.LoadLatestVersion(ctx, tx, s.svc.scope, documentID); err != nil {
|
|
||||||
return fmt.Errorf("cannot load latest version: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if dv.Status == coredata.DocumentVersionStatusPendingApproval {
|
profiles := &coredata.MembershipProfiles{}
|
||||||
return &ErrDocumentVersionPendingApproval{}
|
if err := profiles.LoadByIDs(ctx, tx, s.svc.scope, req.ApproverIDs); err != nil {
|
||||||
|
return fmt.Errorf("cannot load approver profiles: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
now := time.Now()
|
||||||
|
for _, p := range *profiles {
|
||||||
|
if p.ContractEndDate != nil && p.ContractEndDate.Before(now) {
|
||||||
|
return &ErrProfileContractEnded{ProfileID: p.ID}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
document, documentVersion, err = s.publishMajorVersionInTx(ctx, tx, documentID, changelog, false)
|
document := &coredata.Document{}
|
||||||
|
if err := document.LoadByID(ctx, tx, s.svc.scope, req.DocumentID); err != nil {
|
||||||
|
return fmt.Errorf("cannot load document: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if document.ArchivedAt != nil {
|
||||||
|
return &ErrDocumentArchived{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if dv.Status != coredata.DocumentVersionStatusDraft {
|
||||||
|
return &ErrDocumentVersionNotDraft{}
|
||||||
|
}
|
||||||
|
|
||||||
|
quorum, err := s.svc.DocumentApprovals.RequestApprovalInTx(ctx, tx, document, dv, req.ApproverIDs, &req.Changelog)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot publish major version: %w", err)
|
return fmt.Errorf("cannot request approval: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defaultApprovers := &coredata.DocumentDefaultApprovers{}
|
||||||
|
if err := defaultApprovers.MergeByDocumentID(ctx, tx, s.svc.scope, req.DocumentID, document.OrganizationID, req.ApproverIDs); err != nil {
|
||||||
|
return fmt.Errorf("cannot update default approvers: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Document = document
|
||||||
|
result.Version = dv
|
||||||
|
result.Quorum = quorum
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return document, documentVersion, nil
|
return result, nil
|
||||||
}
|
|
||||||
|
|
||||||
func (s *DocumentService) PublishMinorVersion(
|
|
||||||
ctx context.Context,
|
|
||||||
documentID gid.GID,
|
|
||||||
publishedBy gid.GID,
|
|
||||||
changelog *string,
|
|
||||||
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
|
||||||
var document *coredata.Document
|
|
||||||
var documentVersion *coredata.DocumentVersion
|
|
||||||
|
|
||||||
err := s.svc.pg.WithTx(
|
|
||||||
ctx,
|
|
||||||
func(ctx context.Context, tx pg.Tx) error {
|
|
||||||
dv := &coredata.DocumentVersion{}
|
|
||||||
if err := dv.LoadLatestVersion(ctx, tx, s.svc.scope, documentID); err != nil {
|
|
||||||
return fmt.Errorf("cannot load latest version: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if dv.Status == coredata.DocumentVersionStatusPendingApproval {
|
|
||||||
return &ErrDocumentVersionPendingApproval{}
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
|
|
||||||
document, documentVersion, err = s.publishMinorVersionInTx(ctx, tx, documentID, changelog, false)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot publish minor version: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return document, documentVersion, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DocumentService) Create(
|
func (s *DocumentService) Create(
|
||||||
@@ -2788,6 +2805,10 @@ func (s *DocumentService) publishMinorVersionInTx(
|
|||||||
return document, documentVersion, nil
|
return document, documentVersion, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if document.CurrentPublishedMajor == nil || document.CurrentPublishedMinor == nil {
|
||||||
|
return nil, nil, &ErrCannotPublishMinorWithoutMajor{}
|
||||||
|
}
|
||||||
|
|
||||||
document.CurrentPublishedMajor = &documentVersion.Major
|
document.CurrentPublishedMajor = &documentVersion.Major
|
||||||
document.CurrentPublishedMinor = &documentVersion.Minor
|
document.CurrentPublishedMinor = &documentVersion.Minor
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ func (s *GeneratedDocumentService) PublishStatementOfApplicability(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
statementOfApplicabilityID gid.GID,
|
statementOfApplicabilityID gid.GID,
|
||||||
approverIDs []gid.GID,
|
approverIDs []gid.GID,
|
||||||
|
minor bool,
|
||||||
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
||||||
var (
|
var (
|
||||||
document *coredata.Document
|
document *coredata.Document
|
||||||
@@ -109,35 +110,21 @@ func (s *GeneratedDocumentService) PublishStatementOfApplicability(
|
|||||||
document = existingDoc
|
document = existingDoc
|
||||||
}
|
}
|
||||||
|
|
||||||
newMajor := nextDocumentMajor(document)
|
|
||||||
|
|
||||||
versionStatus := coredata.DocumentVersionStatusPublished
|
|
||||||
var publishedAt *time.Time
|
|
||||||
if len(approverIDs) > 0 {
|
|
||||||
versionStatus = coredata.DocumentVersionStatusDraft
|
|
||||||
} else {
|
|
||||||
publishedAt = &now
|
|
||||||
}
|
|
||||||
|
|
||||||
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
||||||
documentVersion = &coredata.DocumentVersion{
|
documentVersion = &coredata.DocumentVersion{
|
||||||
ID: documentVersionID,
|
ID: documentVersionID,
|
||||||
OrganizationID: soa.OrganizationID,
|
OrganizationID: soa.OrganizationID,
|
||||||
DocumentID: document.ID,
|
DocumentID: document.ID,
|
||||||
Title: soa.Name,
|
Title: soa.Name,
|
||||||
Major: newMajor,
|
|
||||||
Minor: 0,
|
|
||||||
Content: prosemirrorJSON,
|
Content: prosemirrorJSON,
|
||||||
Status: versionStatus,
|
|
||||||
Classification: coredata.DocumentClassificationConfidential,
|
Classification: coredata.DocumentClassificationConfidential,
|
||||||
DocumentType: coredata.DocumentTypeStatementOfApplicability,
|
DocumentType: coredata.DocumentTypeStatementOfApplicability,
|
||||||
Orientation: coredata.DocumentVersionOrientationLandscape,
|
Orientation: coredata.DocumentVersionOrientationLandscape,
|
||||||
PublishedAt: publishedAt,
|
|
||||||
CreatedAt: now,
|
CreatedAt: now,
|
||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.publishOrRequestApproval(ctx, tx, document, documentVersion, soa.OrganizationID, approverIDs, newMajor, now)
|
return s.publishOrRequestApproval(ctx, tx, document, documentVersion, soa.OrganizationID, approverIDs, minor, now)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -299,6 +286,7 @@ func (s *GeneratedDocumentService) PublishDataList(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
organizationID gid.GID,
|
organizationID gid.GID,
|
||||||
approverIDs []gid.GID,
|
approverIDs []gid.GID,
|
||||||
|
minor bool,
|
||||||
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
||||||
var (
|
var (
|
||||||
document *coredata.Document
|
document *coredata.Document
|
||||||
@@ -348,8 +336,6 @@ func (s *GeneratedDocumentService) PublishDataList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hasApprovers := len(approverIDs) > 0
|
|
||||||
|
|
||||||
if existingDoc == nil {
|
if existingDoc == nil {
|
||||||
documentID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentEntityType)
|
documentID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentEntityType)
|
||||||
|
|
||||||
@@ -374,35 +360,21 @@ func (s *GeneratedDocumentService) PublishDataList(
|
|||||||
document = existingDoc
|
document = existingDoc
|
||||||
}
|
}
|
||||||
|
|
||||||
newMajor := nextDocumentMajor(document)
|
|
||||||
|
|
||||||
versionStatus := coredata.DocumentVersionStatusPublished
|
|
||||||
var publishedAt *time.Time
|
|
||||||
if hasApprovers {
|
|
||||||
versionStatus = coredata.DocumentVersionStatusDraft
|
|
||||||
} else {
|
|
||||||
publishedAt = &now
|
|
||||||
}
|
|
||||||
|
|
||||||
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
||||||
documentVersion = &coredata.DocumentVersion{
|
documentVersion = &coredata.DocumentVersion{
|
||||||
ID: documentVersionID,
|
ID: documentVersionID,
|
||||||
OrganizationID: organizationID,
|
OrganizationID: organizationID,
|
||||||
DocumentID: document.ID,
|
DocumentID: document.ID,
|
||||||
Title: "Data",
|
Title: "Data",
|
||||||
Major: newMajor,
|
|
||||||
Minor: 0,
|
|
||||||
Content: prosemirrorJSON,
|
Content: prosemirrorJSON,
|
||||||
Status: versionStatus,
|
|
||||||
Classification: coredata.DocumentClassificationConfidential,
|
Classification: coredata.DocumentClassificationConfidential,
|
||||||
DocumentType: coredata.DocumentTypeRegister,
|
DocumentType: coredata.DocumentTypeRegister,
|
||||||
Orientation: coredata.DocumentVersionOrientationPortrait,
|
Orientation: coredata.DocumentVersionOrientationPortrait,
|
||||||
PublishedAt: publishedAt,
|
|
||||||
CreatedAt: now,
|
CreatedAt: now,
|
||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.publishOrRequestApproval(ctx, tx, document, documentVersion, organizationID, approverIDs, newMajor, now)
|
return s.publishOrRequestApproval(ctx, tx, document, documentVersion, organizationID, approverIDs, minor, now)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -550,6 +522,7 @@ func (s *GeneratedDocumentService) PublishAssetList(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
organizationID gid.GID,
|
organizationID gid.GID,
|
||||||
approverIDs []gid.GID,
|
approverIDs []gid.GID,
|
||||||
|
minor bool,
|
||||||
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
||||||
var (
|
var (
|
||||||
document *coredata.Document
|
document *coredata.Document
|
||||||
@@ -599,8 +572,6 @@ func (s *GeneratedDocumentService) PublishAssetList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hasApprovers := len(approverIDs) > 0
|
|
||||||
|
|
||||||
if existingDoc == nil {
|
if existingDoc == nil {
|
||||||
documentID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentEntityType)
|
documentID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentEntityType)
|
||||||
|
|
||||||
@@ -625,35 +596,21 @@ func (s *GeneratedDocumentService) PublishAssetList(
|
|||||||
document = existingDoc
|
document = existingDoc
|
||||||
}
|
}
|
||||||
|
|
||||||
newMajor := nextDocumentMajor(document)
|
|
||||||
|
|
||||||
versionStatus := coredata.DocumentVersionStatusPublished
|
|
||||||
var publishedAt *time.Time
|
|
||||||
if hasApprovers {
|
|
||||||
versionStatus = coredata.DocumentVersionStatusDraft
|
|
||||||
} else {
|
|
||||||
publishedAt = &now
|
|
||||||
}
|
|
||||||
|
|
||||||
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
||||||
documentVersion = &coredata.DocumentVersion{
|
documentVersion = &coredata.DocumentVersion{
|
||||||
ID: documentVersionID,
|
ID: documentVersionID,
|
||||||
OrganizationID: organizationID,
|
OrganizationID: organizationID,
|
||||||
DocumentID: document.ID,
|
DocumentID: document.ID,
|
||||||
Title: "Assets",
|
Title: "Assets",
|
||||||
Major: newMajor,
|
|
||||||
Minor: 0,
|
|
||||||
Content: prosemirrorJSON,
|
Content: prosemirrorJSON,
|
||||||
Status: versionStatus,
|
|
||||||
Classification: coredata.DocumentClassificationConfidential,
|
Classification: coredata.DocumentClassificationConfidential,
|
||||||
DocumentType: coredata.DocumentTypeRegister,
|
DocumentType: coredata.DocumentTypeRegister,
|
||||||
Orientation: coredata.DocumentVersionOrientationPortrait,
|
Orientation: coredata.DocumentVersionOrientationPortrait,
|
||||||
PublishedAt: publishedAt,
|
|
||||||
CreatedAt: now,
|
CreatedAt: now,
|
||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.publishOrRequestApproval(ctx, tx, document, documentVersion, organizationID, approverIDs, newMajor, now)
|
return s.publishOrRequestApproval(ctx, tx, document, documentVersion, organizationID, approverIDs, minor, now)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -822,6 +779,7 @@ func (s *GeneratedDocumentService) PublishFindingList(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
organizationID gid.GID,
|
organizationID gid.GID,
|
||||||
approverIDs []gid.GID,
|
approverIDs []gid.GID,
|
||||||
|
minor bool,
|
||||||
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
||||||
var (
|
var (
|
||||||
document *coredata.Document
|
document *coredata.Document
|
||||||
@@ -871,8 +829,6 @@ func (s *GeneratedDocumentService) PublishFindingList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hasApprovers := len(approverIDs) > 0
|
|
||||||
|
|
||||||
if existingDoc == nil {
|
if existingDoc == nil {
|
||||||
documentID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentEntityType)
|
documentID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentEntityType)
|
||||||
|
|
||||||
@@ -897,35 +853,21 @@ func (s *GeneratedDocumentService) PublishFindingList(
|
|||||||
document = existingDoc
|
document = existingDoc
|
||||||
}
|
}
|
||||||
|
|
||||||
newMajor := nextDocumentMajor(document)
|
|
||||||
|
|
||||||
versionStatus := coredata.DocumentVersionStatusPublished
|
|
||||||
var publishedAt *time.Time
|
|
||||||
if hasApprovers {
|
|
||||||
versionStatus = coredata.DocumentVersionStatusDraft
|
|
||||||
} else {
|
|
||||||
publishedAt = &now
|
|
||||||
}
|
|
||||||
|
|
||||||
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
||||||
documentVersion = &coredata.DocumentVersion{
|
documentVersion = &coredata.DocumentVersion{
|
||||||
ID: documentVersionID,
|
ID: documentVersionID,
|
||||||
OrganizationID: organizationID,
|
OrganizationID: organizationID,
|
||||||
DocumentID: document.ID,
|
DocumentID: document.ID,
|
||||||
Title: "Findings",
|
Title: "Findings",
|
||||||
Major: newMajor,
|
|
||||||
Minor: 0,
|
|
||||||
Content: prosemirrorJSON,
|
Content: prosemirrorJSON,
|
||||||
Status: versionStatus,
|
|
||||||
Classification: coredata.DocumentClassificationConfidential,
|
Classification: coredata.DocumentClassificationConfidential,
|
||||||
DocumentType: coredata.DocumentTypeRegister,
|
DocumentType: coredata.DocumentTypeRegister,
|
||||||
Orientation: coredata.DocumentVersionOrientationLandscape,
|
Orientation: coredata.DocumentVersionOrientationLandscape,
|
||||||
PublishedAt: publishedAt,
|
|
||||||
CreatedAt: now,
|
CreatedAt: now,
|
||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.publishOrRequestApproval(ctx, tx, document, documentVersion, organizationID, approverIDs, newMajor, now)
|
return s.publishOrRequestApproval(ctx, tx, document, documentVersion, organizationID, approverIDs, minor, now)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1139,6 +1081,7 @@ func (s *GeneratedDocumentService) PublishObligationList(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
organizationID gid.GID,
|
organizationID gid.GID,
|
||||||
approverIDs []gid.GID,
|
approverIDs []gid.GID,
|
||||||
|
minor bool,
|
||||||
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
||||||
var (
|
var (
|
||||||
document *coredata.Document
|
document *coredata.Document
|
||||||
@@ -1188,8 +1131,6 @@ func (s *GeneratedDocumentService) PublishObligationList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hasApprovers := len(approverIDs) > 0
|
|
||||||
|
|
||||||
if existingDoc == nil {
|
if existingDoc == nil {
|
||||||
documentID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentEntityType)
|
documentID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentEntityType)
|
||||||
|
|
||||||
@@ -1214,35 +1155,21 @@ func (s *GeneratedDocumentService) PublishObligationList(
|
|||||||
document = existingDoc
|
document = existingDoc
|
||||||
}
|
}
|
||||||
|
|
||||||
newMajor := nextDocumentMajor(document)
|
|
||||||
|
|
||||||
versionStatus := coredata.DocumentVersionStatusPublished
|
|
||||||
var publishedAt *time.Time
|
|
||||||
if hasApprovers {
|
|
||||||
versionStatus = coredata.DocumentVersionStatusDraft
|
|
||||||
} else {
|
|
||||||
publishedAt = &now
|
|
||||||
}
|
|
||||||
|
|
||||||
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
||||||
documentVersion = &coredata.DocumentVersion{
|
documentVersion = &coredata.DocumentVersion{
|
||||||
ID: documentVersionID,
|
ID: documentVersionID,
|
||||||
OrganizationID: organizationID,
|
OrganizationID: organizationID,
|
||||||
DocumentID: document.ID,
|
DocumentID: document.ID,
|
||||||
Title: "Obligations",
|
Title: "Obligations",
|
||||||
Major: newMajor,
|
|
||||||
Minor: 0,
|
|
||||||
Content: prosemirrorJSON,
|
Content: prosemirrorJSON,
|
||||||
Status: versionStatus,
|
|
||||||
Classification: coredata.DocumentClassificationConfidential,
|
Classification: coredata.DocumentClassificationConfidential,
|
||||||
DocumentType: coredata.DocumentTypeRegister,
|
DocumentType: coredata.DocumentTypeRegister,
|
||||||
Orientation: coredata.DocumentVersionOrientationLandscape,
|
Orientation: coredata.DocumentVersionOrientationLandscape,
|
||||||
PublishedAt: publishedAt,
|
|
||||||
CreatedAt: now,
|
CreatedAt: now,
|
||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.publishOrRequestApproval(ctx, tx, document, documentVersion, organizationID, approverIDs, newMajor, now)
|
return s.publishOrRequestApproval(ctx, tx, document, documentVersion, organizationID, approverIDs, minor, now)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1424,6 +1351,7 @@ func (s *GeneratedDocumentService) PublishProcessingActivityList(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
organizationID gid.GID,
|
organizationID gid.GID,
|
||||||
approverIDs []gid.GID,
|
approverIDs []gid.GID,
|
||||||
|
minor bool,
|
||||||
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
||||||
var (
|
var (
|
||||||
document *coredata.Document
|
document *coredata.Document
|
||||||
@@ -1473,8 +1401,6 @@ func (s *GeneratedDocumentService) PublishProcessingActivityList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hasApprovers := len(approverIDs) > 0
|
|
||||||
|
|
||||||
if existingDoc == nil {
|
if existingDoc == nil {
|
||||||
documentID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentEntityType)
|
documentID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentEntityType)
|
||||||
|
|
||||||
@@ -1499,35 +1425,21 @@ func (s *GeneratedDocumentService) PublishProcessingActivityList(
|
|||||||
document = existingDoc
|
document = existingDoc
|
||||||
}
|
}
|
||||||
|
|
||||||
newMajor := nextDocumentMajor(document)
|
|
||||||
|
|
||||||
versionStatus := coredata.DocumentVersionStatusPublished
|
|
||||||
var publishedAt *time.Time
|
|
||||||
if hasApprovers {
|
|
||||||
versionStatus = coredata.DocumentVersionStatusDraft
|
|
||||||
} else {
|
|
||||||
publishedAt = &now
|
|
||||||
}
|
|
||||||
|
|
||||||
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
||||||
documentVersion = &coredata.DocumentVersion{
|
documentVersion = &coredata.DocumentVersion{
|
||||||
ID: documentVersionID,
|
ID: documentVersionID,
|
||||||
OrganizationID: organizationID,
|
OrganizationID: organizationID,
|
||||||
DocumentID: document.ID,
|
DocumentID: document.ID,
|
||||||
Title: "Processing Activities",
|
Title: "Processing Activities",
|
||||||
Major: newMajor,
|
|
||||||
Minor: 0,
|
|
||||||
Content: prosemirrorJSON,
|
Content: prosemirrorJSON,
|
||||||
Status: versionStatus,
|
|
||||||
Classification: coredata.DocumentClassificationConfidential,
|
Classification: coredata.DocumentClassificationConfidential,
|
||||||
DocumentType: coredata.DocumentTypeRegister,
|
DocumentType: coredata.DocumentTypeRegister,
|
||||||
Orientation: coredata.DocumentVersionOrientationPortrait,
|
Orientation: coredata.DocumentVersionOrientationPortrait,
|
||||||
PublishedAt: publishedAt,
|
|
||||||
CreatedAt: now,
|
CreatedAt: now,
|
||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.publishOrRequestApproval(ctx, tx, document, documentVersion, organizationID, approverIDs, newMajor, now)
|
return s.publishOrRequestApproval(ctx, tx, document, documentVersion, organizationID, approverIDs, minor, now)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1804,6 +1716,7 @@ func (s *GeneratedDocumentService) PublishDataProtectionImpactAssessmentList(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
organizationID gid.GID,
|
organizationID gid.GID,
|
||||||
approverIDs []gid.GID,
|
approverIDs []gid.GID,
|
||||||
|
minor bool,
|
||||||
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
||||||
var (
|
var (
|
||||||
document *coredata.Document
|
document *coredata.Document
|
||||||
@@ -1853,8 +1766,6 @@ func (s *GeneratedDocumentService) PublishDataProtectionImpactAssessmentList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hasApprovers := len(approverIDs) > 0
|
|
||||||
|
|
||||||
if existingDoc == nil {
|
if existingDoc == nil {
|
||||||
documentID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentEntityType)
|
documentID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentEntityType)
|
||||||
|
|
||||||
@@ -1879,35 +1790,21 @@ func (s *GeneratedDocumentService) PublishDataProtectionImpactAssessmentList(
|
|||||||
document = existingDoc
|
document = existingDoc
|
||||||
}
|
}
|
||||||
|
|
||||||
newMajor := nextDocumentMajor(document)
|
|
||||||
|
|
||||||
versionStatus := coredata.DocumentVersionStatusPublished
|
|
||||||
var publishedAt *time.Time
|
|
||||||
if hasApprovers {
|
|
||||||
versionStatus = coredata.DocumentVersionStatusDraft
|
|
||||||
} else {
|
|
||||||
publishedAt = &now
|
|
||||||
}
|
|
||||||
|
|
||||||
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
||||||
documentVersion = &coredata.DocumentVersion{
|
documentVersion = &coredata.DocumentVersion{
|
||||||
ID: documentVersionID,
|
ID: documentVersionID,
|
||||||
OrganizationID: organizationID,
|
OrganizationID: organizationID,
|
||||||
DocumentID: document.ID,
|
DocumentID: document.ID,
|
||||||
Title: "Data Protection Impact Assessments",
|
Title: "Data Protection Impact Assessments",
|
||||||
Major: newMajor,
|
|
||||||
Minor: 0,
|
|
||||||
Content: prosemirrorJSON,
|
Content: prosemirrorJSON,
|
||||||
Status: versionStatus,
|
|
||||||
Classification: coredata.DocumentClassificationConfidential,
|
Classification: coredata.DocumentClassificationConfidential,
|
||||||
DocumentType: coredata.DocumentTypeRegister,
|
DocumentType: coredata.DocumentTypeRegister,
|
||||||
Orientation: coredata.DocumentVersionOrientationPortrait,
|
Orientation: coredata.DocumentVersionOrientationPortrait,
|
||||||
PublishedAt: publishedAt,
|
|
||||||
CreatedAt: now,
|
CreatedAt: now,
|
||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.publishOrRequestApproval(ctx, tx, document, documentVersion, organizationID, approverIDs, newMajor, now)
|
return s.publishOrRequestApproval(ctx, tx, document, documentVersion, organizationID, approverIDs, minor, now)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -2029,6 +1926,7 @@ func (s *GeneratedDocumentService) PublishTransferImpactAssessmentList(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
organizationID gid.GID,
|
organizationID gid.GID,
|
||||||
approverIDs []gid.GID,
|
approverIDs []gid.GID,
|
||||||
|
minor bool,
|
||||||
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
||||||
var (
|
var (
|
||||||
document *coredata.Document
|
document *coredata.Document
|
||||||
@@ -2078,8 +1976,6 @@ func (s *GeneratedDocumentService) PublishTransferImpactAssessmentList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hasApprovers := len(approverIDs) > 0
|
|
||||||
|
|
||||||
if existingDoc == nil {
|
if existingDoc == nil {
|
||||||
documentID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentEntityType)
|
documentID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentEntityType)
|
||||||
|
|
||||||
@@ -2104,35 +2000,21 @@ func (s *GeneratedDocumentService) PublishTransferImpactAssessmentList(
|
|||||||
document = existingDoc
|
document = existingDoc
|
||||||
}
|
}
|
||||||
|
|
||||||
newMajor := nextDocumentMajor(document)
|
|
||||||
|
|
||||||
versionStatus := coredata.DocumentVersionStatusPublished
|
|
||||||
var publishedAt *time.Time
|
|
||||||
if hasApprovers {
|
|
||||||
versionStatus = coredata.DocumentVersionStatusDraft
|
|
||||||
} else {
|
|
||||||
publishedAt = &now
|
|
||||||
}
|
|
||||||
|
|
||||||
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
||||||
documentVersion = &coredata.DocumentVersion{
|
documentVersion = &coredata.DocumentVersion{
|
||||||
ID: documentVersionID,
|
ID: documentVersionID,
|
||||||
OrganizationID: organizationID,
|
OrganizationID: organizationID,
|
||||||
DocumentID: document.ID,
|
DocumentID: document.ID,
|
||||||
Title: "Transfer Impact Assessments",
|
Title: "Transfer Impact Assessments",
|
||||||
Major: newMajor,
|
|
||||||
Minor: 0,
|
|
||||||
Content: prosemirrorJSON,
|
Content: prosemirrorJSON,
|
||||||
Status: versionStatus,
|
|
||||||
Classification: coredata.DocumentClassificationConfidential,
|
Classification: coredata.DocumentClassificationConfidential,
|
||||||
DocumentType: coredata.DocumentTypeRegister,
|
DocumentType: coredata.DocumentTypeRegister,
|
||||||
Orientation: coredata.DocumentVersionOrientationPortrait,
|
Orientation: coredata.DocumentVersionOrientationPortrait,
|
||||||
PublishedAt: publishedAt,
|
|
||||||
CreatedAt: now,
|
CreatedAt: now,
|
||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.publishOrRequestApproval(ctx, tx, document, documentVersion, organizationID, approverIDs, newMajor, now)
|
return s.publishOrRequestApproval(ctx, tx, document, documentVersion, organizationID, approverIDs, minor, now)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -2254,6 +2136,7 @@ func (s *GeneratedDocumentService) PublishVendorList(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
organizationID gid.GID,
|
organizationID gid.GID,
|
||||||
approverIDs []gid.GID,
|
approverIDs []gid.GID,
|
||||||
|
minor bool,
|
||||||
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
||||||
// Phase 1: collect data and render the prosemirror document outside any
|
// Phase 1: collect data and render the prosemirror document outside any
|
||||||
// write transaction. Both the bulk reads of vendors + sub-entities and the
|
// write transaction. Both the bulk reads of vendors + sub-entities and the
|
||||||
@@ -2316,8 +2199,6 @@ func (s *GeneratedDocumentService) PublishVendorList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hasApprovers := len(approverIDs) > 0
|
|
||||||
|
|
||||||
if existingDoc == nil {
|
if existingDoc == nil {
|
||||||
documentID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentEntityType)
|
documentID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentEntityType)
|
||||||
|
|
||||||
@@ -2342,35 +2223,21 @@ func (s *GeneratedDocumentService) PublishVendorList(
|
|||||||
document = existingDoc
|
document = existingDoc
|
||||||
}
|
}
|
||||||
|
|
||||||
newMajor := nextDocumentMajor(document)
|
|
||||||
|
|
||||||
versionStatus := coredata.DocumentVersionStatusPublished
|
|
||||||
var publishedAt *time.Time
|
|
||||||
if hasApprovers {
|
|
||||||
versionStatus = coredata.DocumentVersionStatusDraft
|
|
||||||
} else {
|
|
||||||
publishedAt = &now
|
|
||||||
}
|
|
||||||
|
|
||||||
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
||||||
documentVersion = &coredata.DocumentVersion{
|
documentVersion = &coredata.DocumentVersion{
|
||||||
ID: documentVersionID,
|
ID: documentVersionID,
|
||||||
OrganizationID: organizationID,
|
OrganizationID: organizationID,
|
||||||
DocumentID: document.ID,
|
DocumentID: document.ID,
|
||||||
Title: "Vendors",
|
Title: "Vendors",
|
||||||
Major: newMajor,
|
|
||||||
Minor: 0,
|
|
||||||
Content: prosemirrorJSON,
|
Content: prosemirrorJSON,
|
||||||
Status: versionStatus,
|
|
||||||
Classification: coredata.DocumentClassificationConfidential,
|
Classification: coredata.DocumentClassificationConfidential,
|
||||||
DocumentType: coredata.DocumentTypeRegister,
|
DocumentType: coredata.DocumentTypeRegister,
|
||||||
Orientation: coredata.DocumentVersionOrientationPortrait,
|
Orientation: coredata.DocumentVersionOrientationPortrait,
|
||||||
PublishedAt: publishedAt,
|
|
||||||
CreatedAt: now,
|
CreatedAt: now,
|
||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.publishOrRequestApproval(ctx, tx, document, documentVersion, organizationID, approverIDs, newMajor, now)
|
return s.publishOrRequestApproval(ctx, tx, document, documentVersion, organizationID, approverIDs, minor, now)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -2771,6 +2638,7 @@ func (s *GeneratedDocumentService) PublishRiskList(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
organizationID gid.GID,
|
organizationID gid.GID,
|
||||||
approverIDs []gid.GID,
|
approverIDs []gid.GID,
|
||||||
|
minor bool,
|
||||||
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
||||||
var (
|
var (
|
||||||
document *coredata.Document
|
document *coredata.Document
|
||||||
@@ -2820,8 +2688,6 @@ func (s *GeneratedDocumentService) PublishRiskList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hasApprovers := len(approverIDs) > 0
|
|
||||||
|
|
||||||
if existingDoc == nil {
|
if existingDoc == nil {
|
||||||
documentID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentEntityType)
|
documentID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentEntityType)
|
||||||
|
|
||||||
@@ -2846,35 +2712,21 @@ func (s *GeneratedDocumentService) PublishRiskList(
|
|||||||
document = existingDoc
|
document = existingDoc
|
||||||
}
|
}
|
||||||
|
|
||||||
newMajor := nextDocumentMajor(document)
|
|
||||||
|
|
||||||
versionStatus := coredata.DocumentVersionStatusPublished
|
|
||||||
var publishedAt *time.Time
|
|
||||||
if hasApprovers {
|
|
||||||
versionStatus = coredata.DocumentVersionStatusDraft
|
|
||||||
} else {
|
|
||||||
publishedAt = &now
|
|
||||||
}
|
|
||||||
|
|
||||||
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
||||||
documentVersion = &coredata.DocumentVersion{
|
documentVersion = &coredata.DocumentVersion{
|
||||||
ID: documentVersionID,
|
ID: documentVersionID,
|
||||||
OrganizationID: organizationID,
|
OrganizationID: organizationID,
|
||||||
DocumentID: document.ID,
|
DocumentID: document.ID,
|
||||||
Title: "Risks",
|
Title: "Risks",
|
||||||
Major: newMajor,
|
|
||||||
Minor: 0,
|
|
||||||
Content: prosemirrorJSON,
|
Content: prosemirrorJSON,
|
||||||
Status: versionStatus,
|
|
||||||
Classification: coredata.DocumentClassificationConfidential,
|
Classification: coredata.DocumentClassificationConfidential,
|
||||||
DocumentType: coredata.DocumentTypeRegister,
|
DocumentType: coredata.DocumentTypeRegister,
|
||||||
Orientation: coredata.DocumentVersionOrientationPortrait,
|
Orientation: coredata.DocumentVersionOrientationPortrait,
|
||||||
PublishedAt: publishedAt,
|
|
||||||
CreatedAt: now,
|
CreatedAt: now,
|
||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.publishOrRequestApproval(ctx, tx, document, documentVersion, organizationID, approverIDs, newMajor, now)
|
return s.publishOrRequestApproval(ctx, tx, document, documentVersion, organizationID, approverIDs, minor, now)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -3039,19 +2891,14 @@ func formatRiskTreatment(t coredata.RiskTreatment) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// nextDocumentMajor returns the major version to use for a new published
|
// publishOrRequestApproval finalises a freshly built generated document
|
||||||
// version of a generated document.
|
// version. The version's Major, Minor, Status and PublishedAt fields are
|
||||||
func nextDocumentMajor(doc *coredata.Document) int {
|
// computed here based on the document's current published state, the minor
|
||||||
if doc.CurrentPublishedMajor != nil {
|
// flag, and whether approvers were provided. When minor is true the version
|
||||||
return *doc.CurrentPublishedMajor + 1
|
// is always published at currentMajor.(currentMinor+1) and approvers are
|
||||||
}
|
// ignored. When minor is false a non-empty approverIDs triggers an approval
|
||||||
return 1
|
// request at (currentMajor+1).0; otherwise the version is published at
|
||||||
}
|
// (currentMajor+1).0.
|
||||||
|
|
||||||
// publishOrRequestApproval inserts a freshly built generated document version
|
|
||||||
// and either requests approval (if approverIDs is non-empty) or marks the
|
|
||||||
// document as currently published at newMajor.0. The pending-approval insert
|
|
||||||
// conflict is mapped to a friendlier error.
|
|
||||||
func (s *GeneratedDocumentService) publishOrRequestApproval(
|
func (s *GeneratedDocumentService) publishOrRequestApproval(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
tx pg.Tx,
|
tx pg.Tx,
|
||||||
@@ -3059,9 +2906,34 @@ func (s *GeneratedDocumentService) publishOrRequestApproval(
|
|||||||
version *coredata.DocumentVersion,
|
version *coredata.DocumentVersion,
|
||||||
organizationID gid.GID,
|
organizationID gid.GID,
|
||||||
approverIDs []gid.GID,
|
approverIDs []gid.GID,
|
||||||
newMajor int,
|
minor bool,
|
||||||
now time.Time,
|
now time.Time,
|
||||||
) error {
|
) error {
|
||||||
|
if minor {
|
||||||
|
if document.CurrentPublishedMajor == nil || document.CurrentPublishedMinor == nil {
|
||||||
|
return &ErrCannotPublishMinorWithoutMajor{}
|
||||||
|
}
|
||||||
|
version.Major = *document.CurrentPublishedMajor
|
||||||
|
version.Minor = *document.CurrentPublishedMinor + 1
|
||||||
|
version.Status = coredata.DocumentVersionStatusPublished
|
||||||
|
version.PublishedAt = &now
|
||||||
|
approverIDs = nil
|
||||||
|
} else {
|
||||||
|
if document.CurrentPublishedMajor != nil {
|
||||||
|
version.Major = *document.CurrentPublishedMajor + 1
|
||||||
|
} else {
|
||||||
|
version.Major = 1
|
||||||
|
}
|
||||||
|
version.Minor = 0
|
||||||
|
if len(approverIDs) > 0 {
|
||||||
|
version.Status = coredata.DocumentVersionStatusDraft
|
||||||
|
version.PublishedAt = nil
|
||||||
|
} else {
|
||||||
|
version.Status = coredata.DocumentVersionStatusPublished
|
||||||
|
version.PublishedAt = &now
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := version.Insert(ctx, tx, s.svc.scope); err != nil {
|
if err := version.Insert(ctx, tx, s.svc.scope); err != nil {
|
||||||
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
||||||
return fmt.Errorf("a version is pending approval, approve or reject it before publishing a new one: %w", err)
|
return fmt.Errorf("a version is pending approval, approve or reject it before publishing a new one: %w", err)
|
||||||
@@ -3080,8 +2952,8 @@ func (s *GeneratedDocumentService) publishOrRequestApproval(
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
document.CurrentPublishedMajor = &newMajor
|
document.CurrentPublishedMajor = &version.Major
|
||||||
document.CurrentPublishedMinor = new(0)
|
document.CurrentPublishedMinor = &version.Minor
|
||||||
document.UpdatedAt = now
|
document.UpdatedAt = now
|
||||||
|
|
||||||
if err := document.Update(ctx, tx, s.svc.scope); err != nil {
|
if err := document.Update(ctx, tx, s.svc.scope); err != nil {
|
||||||
|
|||||||
@@ -403,11 +403,14 @@ func (r *mutationResolver) PublishDataList(ctx context.Context, input types.Publ
|
|||||||
|
|
||||||
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
|
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
|
||||||
|
|
||||||
document, documentVersion, err := prb.GeneratedDocuments.PublishDataList(ctx, input.OrganizationID, input.ApproverIds)
|
document, documentVersion, err := prb.GeneratedDocuments.PublishDataList(ctx, input.OrganizationID, input.ApproverIds, input.Minor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
||||||
return nil, gqlutils.Conflict(ctx, err)
|
return nil, gqlutils.Conflict(ctx, err)
|
||||||
}
|
}
|
||||||
|
if errMinor, ok := errors.AsType[*probo.ErrCannotPublishMinorWithoutMajor](err); ok {
|
||||||
|
return nil, gqlutils.Invalid(ctx, errMinor)
|
||||||
|
}
|
||||||
r.logger.ErrorCtx(ctx, "cannot publish data list", log.Error(err))
|
r.logger.ErrorCtx(ctx, "cannot publish data list", log.Error(err))
|
||||||
return nil, gqlutils.Internal(ctx)
|
return nil, gqlutils.Internal(ctx)
|
||||||
}
|
}
|
||||||
@@ -426,11 +429,14 @@ func (r *mutationResolver) PublishAssetList(ctx context.Context, input types.Pub
|
|||||||
|
|
||||||
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
|
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
|
||||||
|
|
||||||
document, documentVersion, err := prb.GeneratedDocuments.PublishAssetList(ctx, input.OrganizationID, input.ApproverIds)
|
document, documentVersion, err := prb.GeneratedDocuments.PublishAssetList(ctx, input.OrganizationID, input.ApproverIds, input.Minor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
||||||
return nil, gqlutils.Conflict(ctx, err)
|
return nil, gqlutils.Conflict(ctx, err)
|
||||||
}
|
}
|
||||||
|
if errMinor, ok := errors.AsType[*probo.ErrCannotPublishMinorWithoutMajor](err); ok {
|
||||||
|
return nil, gqlutils.Invalid(ctx, errMinor)
|
||||||
|
}
|
||||||
r.logger.ErrorCtx(ctx, "cannot publish asset list", log.Error(err))
|
r.logger.ErrorCtx(ctx, "cannot publish asset list", log.Error(err))
|
||||||
return nil, gqlutils.Internal(ctx)
|
return nil, gqlutils.Internal(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -679,11 +679,14 @@ func (r *mutationResolver) PublishFindingList(ctx context.Context, input types.P
|
|||||||
|
|
||||||
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
|
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
|
||||||
|
|
||||||
document, documentVersion, err := prb.GeneratedDocuments.PublishFindingList(ctx, input.OrganizationID, input.ApproverIds)
|
document, documentVersion, err := prb.GeneratedDocuments.PublishFindingList(ctx, input.OrganizationID, input.ApproverIds, input.Minor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
||||||
return nil, gqlutils.Conflict(ctx, err)
|
return nil, gqlutils.Conflict(ctx, err)
|
||||||
}
|
}
|
||||||
|
if errMinor, ok := errors.AsType[*probo.ErrCannotPublishMinorWithoutMajor](err); ok {
|
||||||
|
return nil, gqlutils.Invalid(ctx, errMinor)
|
||||||
|
}
|
||||||
r.logger.ErrorCtx(ctx, "cannot publish finding list", log.Error(err))
|
r.logger.ErrorCtx(ctx, "cannot publish finding list", log.Error(err))
|
||||||
return nil, gqlutils.Internal(ctx)
|
return nil, gqlutils.Internal(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -771,11 +771,14 @@ func (r *mutationResolver) PublishStatementOfApplicability(ctx context.Context,
|
|||||||
|
|
||||||
prb := r.ProboService(ctx, input.StatementOfApplicabilityID.TenantID())
|
prb := r.ProboService(ctx, input.StatementOfApplicabilityID.TenantID())
|
||||||
|
|
||||||
document, documentVersion, err := prb.GeneratedDocuments.PublishStatementOfApplicability(ctx, input.StatementOfApplicabilityID, input.ApproverIds)
|
document, documentVersion, err := prb.GeneratedDocuments.PublishStatementOfApplicability(ctx, input.StatementOfApplicabilityID, input.ApproverIds, input.Minor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
||||||
return nil, gqlutils.Conflict(ctx, err)
|
return nil, gqlutils.Conflict(ctx, err)
|
||||||
}
|
}
|
||||||
|
if errMinor, ok := errors.AsType[*probo.ErrCannotPublishMinorWithoutMajor](err); ok {
|
||||||
|
return nil, gqlutils.Invalid(ctx, errMinor)
|
||||||
|
}
|
||||||
r.logger.ErrorCtx(ctx, "cannot publish statement of applicability", log.Error(err))
|
r.logger.ErrorCtx(ctx, "cannot publish statement of applicability", log.Error(err))
|
||||||
return nil, gqlutils.Internal(ctx)
|
return nil, gqlutils.Internal(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -274,11 +274,14 @@ func (r *mutationResolver) PublishDataProtectionImpactAssessmentList(ctx context
|
|||||||
|
|
||||||
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
|
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
|
||||||
|
|
||||||
document, documentVersion, err := prb.GeneratedDocuments.PublishDataProtectionImpactAssessmentList(ctx, input.OrganizationID, input.ApproverIds)
|
document, documentVersion, err := prb.GeneratedDocuments.PublishDataProtectionImpactAssessmentList(ctx, input.OrganizationID, input.ApproverIds, input.Minor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
||||||
return nil, gqlutils.Conflict(ctx, err)
|
return nil, gqlutils.Conflict(ctx, err)
|
||||||
}
|
}
|
||||||
|
if errMinor, ok := errors.AsType[*probo.ErrCannotPublishMinorWithoutMajor](err); ok {
|
||||||
|
return nil, gqlutils.Invalid(ctx, errMinor)
|
||||||
|
}
|
||||||
r.logger.ErrorCtx(ctx, "cannot publish data protection impact assessment list", log.Error(err))
|
r.logger.ErrorCtx(ctx, "cannot publish data protection impact assessment list", log.Error(err))
|
||||||
return nil, gqlutils.Internal(ctx)
|
return nil, gqlutils.Internal(ctx)
|
||||||
}
|
}
|
||||||
@@ -297,11 +300,14 @@ func (r *mutationResolver) PublishTransferImpactAssessmentList(ctx context.Conte
|
|||||||
|
|
||||||
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
|
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
|
||||||
|
|
||||||
document, documentVersion, err := prb.GeneratedDocuments.PublishTransferImpactAssessmentList(ctx, input.OrganizationID, input.ApproverIds)
|
document, documentVersion, err := prb.GeneratedDocuments.PublishTransferImpactAssessmentList(ctx, input.OrganizationID, input.ApproverIds, input.Minor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
||||||
return nil, gqlutils.Conflict(ctx, err)
|
return nil, gqlutils.Conflict(ctx, err)
|
||||||
}
|
}
|
||||||
|
if errMinor, ok := errors.AsType[*probo.ErrCannotPublishMinorWithoutMajor](err); ok {
|
||||||
|
return nil, gqlutils.Invalid(ctx, errMinor)
|
||||||
|
}
|
||||||
r.logger.ErrorCtx(ctx, "cannot publish transfer impact assessment list", log.Error(err))
|
r.logger.ErrorCtx(ctx, "cannot publish transfer impact assessment list", log.Error(err))
|
||||||
return nil, gqlutils.Internal(ctx)
|
return nil, gqlutils.Internal(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -980,198 +980,21 @@ func (r *mutationResolver) DeleteDocument(ctx context.Context, input types.Delet
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublishMajorDocumentVersion is the resolver for the publishMajorDocumentVersion field.
|
// PublishDocument is the resolver for the publishDocument field.
|
||||||
func (r *mutationResolver) PublishMajorDocumentVersion(ctx context.Context, input types.PublishMajorDocumentVersionInput) (*types.PublishDocumentVersionPayload, error) {
|
func (r *mutationResolver) PublishDocument(ctx context.Context, input types.PublishDocumentInput) (*types.PublishDocumentPayload, error) {
|
||||||
if err := r.authorize(ctx, input.DocumentID, probo.ActionDocumentVersionPublish); err != nil {
|
action := probo.ActionDocumentVersionPublish
|
||||||
|
if !input.Minor && len(input.ApproverIds) > 0 {
|
||||||
|
action = probo.ActionDocumentVersionRequestApproval
|
||||||
|
}
|
||||||
|
if err := r.authorize(ctx, input.DocumentID, action); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
prb := r.ProboService(ctx, input.DocumentID.TenantID())
|
prb := r.ProboService(ctx, input.DocumentID.TenantID())
|
||||||
|
|
||||||
document, documentVersion, err := prb.Documents.PublishMajorVersion(
|
result, err := prb.Documents.PublishVersion(ctx, probo.PublishDocumentRequest{
|
||||||
ctx,
|
|
||||||
input.DocumentID,
|
|
||||||
authn.IdentityFromContext(ctx).ID,
|
|
||||||
input.Changelog,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
if errArchived, ok := errors.AsType[*probo.ErrDocumentArchived](err); ok {
|
|
||||||
return nil, gqlutils.Conflict(ctx, errArchived)
|
|
||||||
}
|
|
||||||
|
|
||||||
if errNotDraft, ok := errors.AsType[*probo.ErrDocumentVersionNotDraft](err); ok {
|
|
||||||
return nil, gqlutils.Invalid(ctx, errNotDraft)
|
|
||||||
}
|
|
||||||
|
|
||||||
if errPending, ok := errors.AsType[*probo.ErrDocumentVersionPendingApproval](err); ok {
|
|
||||||
return nil, gqlutils.Conflict(ctx, errPending)
|
|
||||||
}
|
|
||||||
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot publish major document version", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.PublishDocumentVersionPayload{
|
|
||||||
Document: types.NewDocument(document),
|
|
||||||
DocumentVersion: types.NewDocumentVersion(documentVersion),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// PublishMinorDocumentVersion is the resolver for the publishMinorDocumentVersion field.
|
|
||||||
func (r *mutationResolver) PublishMinorDocumentVersion(ctx context.Context, input types.PublishMinorDocumentVersionInput) (*types.PublishDocumentVersionPayload, error) {
|
|
||||||
if err := r.authorize(ctx, input.DocumentID, probo.ActionDocumentVersionPublish); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
prb := r.ProboService(ctx, input.DocumentID.TenantID())
|
|
||||||
|
|
||||||
document, documentVersion, err := prb.Documents.PublishMinorVersion(
|
|
||||||
ctx,
|
|
||||||
input.DocumentID,
|
|
||||||
authn.IdentityFromContext(ctx).ID,
|
|
||||||
input.Changelog,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
if errArchived, ok := errors.AsType[*probo.ErrDocumentArchived](err); ok {
|
|
||||||
return nil, gqlutils.Conflict(ctx, errArchived)
|
|
||||||
}
|
|
||||||
|
|
||||||
if errNotDraft, ok := errors.AsType[*probo.ErrDocumentVersionNotDraft](err); ok {
|
|
||||||
return nil, gqlutils.Invalid(ctx, errNotDraft)
|
|
||||||
}
|
|
||||||
|
|
||||||
if errPending, ok := errors.AsType[*probo.ErrDocumentVersionPendingApproval](err); ok {
|
|
||||||
return nil, gqlutils.Conflict(ctx, errPending)
|
|
||||||
}
|
|
||||||
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot publish minor document version", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.PublishDocumentVersionPayload{
|
|
||||||
Document: types.NewDocument(document),
|
|
||||||
DocumentVersion: types.NewDocumentVersion(documentVersion),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// BulkPublishMajorDocumentVersions is the resolver for the bulkPublishMajorDocumentVersions field.
|
|
||||||
func (r *mutationResolver) BulkPublishMajorDocumentVersions(ctx context.Context, input types.BulkPublishDocumentVersionsInput) (*types.BulkPublishDocumentVersionsPayload, error) {
|
|
||||||
if len(input.DocumentIds) == 0 {
|
|
||||||
return &types.BulkPublishDocumentVersionsPayload{
|
|
||||||
DocumentVersions: []*types.DocumentVersion{},
|
|
||||||
Documents: []*types.Document{},
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, documentID := range input.DocumentIds {
|
|
||||||
if err := r.authorize(ctx, documentID, probo.ActionDocumentVersionPublish); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
prb := r.ProboService(ctx, input.DocumentIds[0].TenantID())
|
|
||||||
|
|
||||||
versions, documents, err := prb.DocumentApprovals.BulkPublishMajorVersions(ctx, probo.BulkPublishVersionsRequest{
|
|
||||||
DocumentIDs: input.DocumentIds,
|
|
||||||
Changelog: input.Changelog,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
|
||||||
return nil, gqlutils.NotFound(ctx, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if errArchived, ok := errors.AsType[*probo.ErrDocumentArchived](err); ok {
|
|
||||||
return nil, gqlutils.Conflict(ctx, errArchived)
|
|
||||||
}
|
|
||||||
|
|
||||||
if errNotDraft, ok := errors.AsType[*probo.ErrDocumentVersionNotDraft](err); ok {
|
|
||||||
return nil, gqlutils.Invalid(ctx, errNotDraft)
|
|
||||||
}
|
|
||||||
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot bulk publish major document versions", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
typesVersions := make([]*types.DocumentVersion, len(versions))
|
|
||||||
for i, v := range versions {
|
|
||||||
typesVersions[i] = types.NewDocumentVersion(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
typesDocuments := make([]*types.Document, len(documents))
|
|
||||||
for i, d := range documents {
|
|
||||||
typesDocuments[i] = types.NewDocument(d)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.BulkPublishDocumentVersionsPayload{
|
|
||||||
DocumentVersions: typesVersions,
|
|
||||||
Documents: typesDocuments,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// BulkPublishMinorDocumentVersions is the resolver for the bulkPublishMinorDocumentVersions field.
|
|
||||||
func (r *mutationResolver) BulkPublishMinorDocumentVersions(ctx context.Context, input types.BulkPublishDocumentVersionsInput) (*types.BulkPublishDocumentVersionsPayload, error) {
|
|
||||||
if len(input.DocumentIds) == 0 {
|
|
||||||
return &types.BulkPublishDocumentVersionsPayload{
|
|
||||||
DocumentVersions: []*types.DocumentVersion{},
|
|
||||||
Documents: []*types.Document{},
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, documentID := range input.DocumentIds {
|
|
||||||
if err := r.authorize(ctx, documentID, probo.ActionDocumentVersionPublish); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
prb := r.ProboService(ctx, input.DocumentIds[0].TenantID())
|
|
||||||
|
|
||||||
versions, documents, err := prb.Documents.BulkPublishMinorVersions(ctx, probo.BulkPublishVersionsRequest{
|
|
||||||
DocumentIDs: input.DocumentIds,
|
|
||||||
Changelog: input.Changelog,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
|
||||||
return nil, gqlutils.NotFound(ctx, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if errArchived, ok := errors.AsType[*probo.ErrDocumentArchived](err); ok {
|
|
||||||
return nil, gqlutils.Conflict(ctx, errArchived)
|
|
||||||
}
|
|
||||||
|
|
||||||
if errNotDraft, ok := errors.AsType[*probo.ErrDocumentVersionNotDraft](err); ok {
|
|
||||||
return nil, gqlutils.Invalid(ctx, errNotDraft)
|
|
||||||
}
|
|
||||||
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot bulk publish minor document versions", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
typesVersions := make([]*types.DocumentVersion, len(versions))
|
|
||||||
for i, v := range versions {
|
|
||||||
typesVersions[i] = types.NewDocumentVersion(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
typesDocuments := make([]*types.Document, len(documents))
|
|
||||||
for i, d := range documents {
|
|
||||||
typesDocuments[i] = types.NewDocument(d)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.BulkPublishDocumentVersionsPayload{
|
|
||||||
DocumentVersions: typesVersions,
|
|
||||||
Documents: typesDocuments,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RequestDocumentVersionApproval is the resolver for the requestDocumentVersionApproval field.
|
|
||||||
func (r *mutationResolver) RequestDocumentVersionApproval(ctx context.Context, input types.RequestDocumentVersionApprovalInput) (*types.RequestDocumentVersionApprovalPayload, error) {
|
|
||||||
if err := r.authorize(ctx, input.DocumentID, probo.ActionDocumentVersionRequestApproval); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
prb := r.ProboService(ctx, input.DocumentID.TenantID())
|
|
||||||
|
|
||||||
quorum, err := prb.DocumentApprovals.RequestApproval(ctx, probo.RequestApprovalRequest{
|
|
||||||
DocumentID: input.DocumentID,
|
DocumentID: input.DocumentID,
|
||||||
|
Minor: input.Minor,
|
||||||
ApproverIDs: input.ApproverIds,
|
ApproverIDs: input.ApproverIds,
|
||||||
Changelog: input.Changelog,
|
Changelog: input.Changelog,
|
||||||
})
|
})
|
||||||
@@ -1181,7 +1004,15 @@ func (r *mutationResolver) RequestDocumentVersionApproval(ctx context.Context, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
if errNotDraft, ok := errors.AsType[*probo.ErrDocumentVersionNotDraft](err); ok {
|
if errNotDraft, ok := errors.AsType[*probo.ErrDocumentVersionNotDraft](err); ok {
|
||||||
return nil, gqlutils.Conflict(ctx, errNotDraft)
|
return nil, gqlutils.Invalid(ctx, errNotDraft)
|
||||||
|
}
|
||||||
|
|
||||||
|
if errPending, ok := errors.AsType[*probo.ErrDocumentVersionPendingApproval](err); ok {
|
||||||
|
return nil, gqlutils.Conflict(ctx, errPending)
|
||||||
|
}
|
||||||
|
|
||||||
|
if errMinor, ok := errors.AsType[*probo.ErrCannotPublishMinorWithoutMajor](err); ok {
|
||||||
|
return nil, gqlutils.Invalid(ctx, errMinor)
|
||||||
}
|
}
|
||||||
|
|
||||||
if errContractEnded, ok := errors.AsType[*probo.ErrProfileContractEnded](err); ok {
|
if errContractEnded, ok := errors.AsType[*probo.ErrProfileContractEnded](err); ok {
|
||||||
@@ -1192,12 +1023,72 @@ func (r *mutationResolver) RequestDocumentVersionApproval(ctx context.Context, i
|
|||||||
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
||||||
}
|
}
|
||||||
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot request document version approval", log.Error(err))
|
r.logger.ErrorCtx(ctx, "cannot publish document", log.Error(err))
|
||||||
return nil, gqlutils.Internal(ctx)
|
return nil, gqlutils.Internal(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &types.RequestDocumentVersionApprovalPayload{
|
payload := &types.PublishDocumentPayload{
|
||||||
ApprovalQuorum: types.NewDocumentVersionApprovalQuorum(quorum),
|
Document: types.NewDocument(result.Document),
|
||||||
|
DocumentVersion: types.NewDocumentVersion(result.Version),
|
||||||
|
}
|
||||||
|
if result.Quorum != nil {
|
||||||
|
payload.ApprovalQuorum = types.NewDocumentVersionApprovalQuorum(result.Quorum)
|
||||||
|
}
|
||||||
|
return payload, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BulkPublishDocuments is the resolver for the bulkPublishDocuments field.
|
||||||
|
func (r *mutationResolver) BulkPublishDocuments(ctx context.Context, input types.BulkPublishDocumentsInput) (*types.BulkPublishDocumentsPayload, error) {
|
||||||
|
if len(input.DocumentIds) == 0 {
|
||||||
|
return &types.BulkPublishDocumentsPayload{
|
||||||
|
DocumentVersions: []*types.DocumentVersion{},
|
||||||
|
Documents: []*types.Document{},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, documentID := range input.DocumentIds {
|
||||||
|
if err := r.authorize(ctx, documentID, probo.ActionDocumentVersionPublish); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prb := r.ProboService(ctx, input.DocumentIds[0].TenantID())
|
||||||
|
|
||||||
|
versions, documents, err := prb.DocumentApprovals.BulkPublishVersions(ctx, probo.BulkPublishVersionsRequest{
|
||||||
|
DocumentIDs: input.DocumentIds,
|
||||||
|
Minor: input.Minor,
|
||||||
|
Changelog: input.Changelog,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||||
|
return nil, gqlutils.NotFound(ctx, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if errArchived, ok := errors.AsType[*probo.ErrDocumentArchived](err); ok {
|
||||||
|
return nil, gqlutils.Conflict(ctx, errArchived)
|
||||||
|
}
|
||||||
|
|
||||||
|
if errNotDraft, ok := errors.AsType[*probo.ErrDocumentVersionNotDraft](err); ok {
|
||||||
|
return nil, gqlutils.Invalid(ctx, errNotDraft)
|
||||||
|
}
|
||||||
|
|
||||||
|
r.logger.ErrorCtx(ctx, "cannot bulk publish documents", log.Error(err))
|
||||||
|
return nil, gqlutils.Internal(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
typesVersions := make([]*types.DocumentVersion, len(versions))
|
||||||
|
for i, v := range versions {
|
||||||
|
typesVersions[i] = types.NewDocumentVersion(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
typesDocuments := make([]*types.Document, len(documents))
|
||||||
|
for i, d := range documents {
|
||||||
|
typesDocuments[i] = types.NewDocument(d)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.BulkPublishDocumentsPayload{
|
||||||
|
DocumentVersions: typesVersions,
|
||||||
|
Documents: typesDocuments,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -219,6 +219,7 @@ type DeleteDatumPayload {
|
|||||||
input PublishDataListInput {
|
input PublishDataListInput {
|
||||||
organizationId: ID!
|
organizationId: ID!
|
||||||
approverIds: [ID!]
|
approverIds: [ID!]
|
||||||
|
minor: Boolean!
|
||||||
}
|
}
|
||||||
|
|
||||||
type PublishDataListPayload {
|
type PublishDataListPayload {
|
||||||
@@ -229,6 +230,7 @@ type PublishDataListPayload {
|
|||||||
input PublishAssetListInput {
|
input PublishAssetListInput {
|
||||||
organizationId: ID!
|
organizationId: ID!
|
||||||
approverIds: [ID!]
|
approverIds: [ID!]
|
||||||
|
minor: Boolean!
|
||||||
}
|
}
|
||||||
|
|
||||||
type PublishAssetListPayload {
|
type PublishAssetListPayload {
|
||||||
|
|||||||
@@ -276,6 +276,7 @@ extend type Mutation {
|
|||||||
input PublishFindingListInput {
|
input PublishFindingListInput {
|
||||||
organizationId: ID!
|
organizationId: ID!
|
||||||
approverIds: [ID!]
|
approverIds: [ID!]
|
||||||
|
minor: Boolean!
|
||||||
}
|
}
|
||||||
|
|
||||||
type PublishFindingListPayload {
|
type PublishFindingListPayload {
|
||||||
|
|||||||
@@ -375,6 +375,7 @@ input DeleteStatementOfApplicabilityInput {
|
|||||||
input PublishStatementOfApplicabilityInput {
|
input PublishStatementOfApplicabilityInput {
|
||||||
statementOfApplicabilityId: ID!
|
statementOfApplicabilityId: ID!
|
||||||
approverIds: [ID!]
|
approverIds: [ID!]
|
||||||
|
minor: Boolean!
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateControlPayload {
|
type CreateControlPayload {
|
||||||
|
|||||||
@@ -184,11 +184,13 @@ input DeleteTransferImpactAssessmentInput {
|
|||||||
input PublishDataProtectionImpactAssessmentListInput {
|
input PublishDataProtectionImpactAssessmentListInput {
|
||||||
organizationId: ID!
|
organizationId: ID!
|
||||||
approverIds: [ID!]
|
approverIds: [ID!]
|
||||||
|
minor: Boolean!
|
||||||
}
|
}
|
||||||
|
|
||||||
input PublishTransferImpactAssessmentListInput {
|
input PublishTransferImpactAssessmentListInput {
|
||||||
organizationId: ID!
|
organizationId: ID!
|
||||||
approverIds: [ID!]
|
approverIds: [ID!]
|
||||||
|
minor: Boolean!
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateDataProtectionImpactAssessmentPayload {
|
type CreateDataProtectionImpactAssessmentPayload {
|
||||||
|
|||||||
@@ -536,21 +536,12 @@ extend type Mutation {
|
|||||||
archiveDocument(input: ArchiveDocumentInput!): ArchiveDocumentPayload!
|
archiveDocument(input: ArchiveDocumentInput!): ArchiveDocumentPayload!
|
||||||
unarchiveDocument(input: UnarchiveDocumentInput!): UnarchiveDocumentPayload!
|
unarchiveDocument(input: UnarchiveDocumentInput!): UnarchiveDocumentPayload!
|
||||||
deleteDocument(input: DeleteDocumentInput!): DeleteDocumentPayload!
|
deleteDocument(input: DeleteDocumentInput!): DeleteDocumentPayload!
|
||||||
publishMajorDocumentVersion(
|
publishDocument(
|
||||||
input: PublishMajorDocumentVersionInput!
|
input: PublishDocumentInput!
|
||||||
): PublishDocumentVersionPayload!
|
): PublishDocumentPayload!
|
||||||
publishMinorDocumentVersion(
|
bulkPublishDocuments(
|
||||||
input: PublishMinorDocumentVersionInput!
|
input: BulkPublishDocumentsInput!
|
||||||
): PublishDocumentVersionPayload!
|
): BulkPublishDocumentsPayload!
|
||||||
bulkPublishMajorDocumentVersions(
|
|
||||||
input: BulkPublishDocumentVersionsInput!
|
|
||||||
): BulkPublishDocumentVersionsPayload!
|
|
||||||
bulkPublishMinorDocumentVersions(
|
|
||||||
input: BulkPublishDocumentVersionsInput!
|
|
||||||
): BulkPublishDocumentVersionsPayload!
|
|
||||||
requestDocumentVersionApproval(
|
|
||||||
input: RequestDocumentVersionApprovalInput!
|
|
||||||
): RequestDocumentVersionApprovalPayload!
|
|
||||||
voidDocumentVersionApproval(
|
voidDocumentVersionApproval(
|
||||||
input: VoidDocumentVersionApprovalInput!
|
input: VoidDocumentVersionApprovalInput!
|
||||||
): VoidDocumentVersionApprovalPayload!
|
): VoidDocumentVersionApprovalPayload!
|
||||||
@@ -641,25 +632,17 @@ input ExportEmployeeDocumentVersionPDFInput {
|
|||||||
documentVersionId: ID!
|
documentVersionId: ID!
|
||||||
}
|
}
|
||||||
|
|
||||||
input PublishMajorDocumentVersionInput {
|
input PublishDocumentInput {
|
||||||
documentId: ID!
|
documentId: ID!
|
||||||
changelog: String
|
minor: Boolean!
|
||||||
}
|
approverIds: [ID!]
|
||||||
|
|
||||||
input PublishMinorDocumentVersionInput {
|
|
||||||
documentId: ID!
|
|
||||||
changelog: String
|
|
||||||
}
|
|
||||||
|
|
||||||
input BulkPublishDocumentVersionsInput {
|
|
||||||
documentIds: [ID!]!
|
|
||||||
changelog: String!
|
changelog: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
input RequestDocumentVersionApprovalInput {
|
input BulkPublishDocumentsInput {
|
||||||
documentId: ID!
|
documentIds: [ID!]!
|
||||||
approverIds: [ID!]!
|
minor: Boolean!
|
||||||
changelog: String
|
changelog: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
input VoidDocumentVersionApprovalInput {
|
input VoidDocumentVersionApprovalInput {
|
||||||
@@ -756,20 +739,17 @@ type ExportEmployeeDocumentVersionPDFPayload {
|
|||||||
data: String!
|
data: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
type PublishDocumentVersionPayload {
|
type PublishDocumentPayload {
|
||||||
document: Document!
|
document: Document!
|
||||||
documentVersion: DocumentVersion!
|
documentVersion: DocumentVersion!
|
||||||
|
approvalQuorum: DocumentVersionApprovalQuorum
|
||||||
}
|
}
|
||||||
|
|
||||||
type BulkPublishDocumentVersionsPayload {
|
type BulkPublishDocumentsPayload {
|
||||||
documentVersions: [DocumentVersion!]!
|
documentVersions: [DocumentVersion!]!
|
||||||
documents: [Document!]!
|
documents: [Document!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
type RequestDocumentVersionApprovalPayload {
|
|
||||||
approvalQuorum: DocumentVersionApprovalQuorum!
|
|
||||||
}
|
|
||||||
|
|
||||||
type VoidDocumentVersionApprovalPayload {
|
type VoidDocumentVersionApprovalPayload {
|
||||||
approvalQuorum: DocumentVersionApprovalQuorum!
|
approvalQuorum: DocumentVersionApprovalQuorum!
|
||||||
documentVersion: DocumentVersion!
|
documentVersion: DocumentVersion!
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ extend type Mutation {
|
|||||||
input PublishObligationListInput {
|
input PublishObligationListInput {
|
||||||
organizationId: ID!
|
organizationId: ID!
|
||||||
approverIds: [ID!]
|
approverIds: [ID!]
|
||||||
|
minor: Boolean!
|
||||||
}
|
}
|
||||||
|
|
||||||
type PublishObligationListPayload {
|
type PublishObligationListPayload {
|
||||||
|
|||||||
@@ -262,6 +262,7 @@ input DeleteProcessingActivityInput {
|
|||||||
input PublishProcessingActivityListInput {
|
input PublishProcessingActivityListInput {
|
||||||
organizationId: ID!
|
organizationId: ID!
|
||||||
approverIds: [ID!]
|
approverIds: [ID!]
|
||||||
|
minor: Boolean!
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateProcessingActivityPayload {
|
type CreateProcessingActivityPayload {
|
||||||
|
|||||||
@@ -157,6 +157,7 @@ extend type Mutation {
|
|||||||
input PublishRiskListInput {
|
input PublishRiskListInput {
|
||||||
organizationId: ID!
|
organizationId: ID!
|
||||||
approverIds: [ID!]
|
approverIds: [ID!]
|
||||||
|
minor: Boolean!
|
||||||
}
|
}
|
||||||
|
|
||||||
type PublishRiskListPayload {
|
type PublishRiskListPayload {
|
||||||
|
|||||||
@@ -465,6 +465,7 @@ extend type Mutation {
|
|||||||
input PublishVendorListInput {
|
input PublishVendorListInput {
|
||||||
organizationId: ID!
|
organizationId: ID!
|
||||||
approverIds: [ID!]
|
approverIds: [ID!]
|
||||||
|
minor: Boolean!
|
||||||
}
|
}
|
||||||
|
|
||||||
type PublishVendorListPayload {
|
type PublishVendorListPayload {
|
||||||
|
|||||||
@@ -120,11 +120,14 @@ func (r *mutationResolver) PublishObligationList(ctx context.Context, input type
|
|||||||
|
|
||||||
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
|
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
|
||||||
|
|
||||||
document, documentVersion, err := prb.GeneratedDocuments.PublishObligationList(ctx, input.OrganizationID, input.ApproverIds)
|
document, documentVersion, err := prb.GeneratedDocuments.PublishObligationList(ctx, input.OrganizationID, input.ApproverIds, input.Minor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
||||||
return nil, gqlutils.Conflict(ctx, err)
|
return nil, gqlutils.Conflict(ctx, err)
|
||||||
}
|
}
|
||||||
|
if errMinor, ok := errors.AsType[*probo.ErrCannotPublishMinorWithoutMajor](err); ok {
|
||||||
|
return nil, gqlutils.Invalid(ctx, errMinor)
|
||||||
|
}
|
||||||
r.logger.ErrorCtx(ctx, "cannot publish obligation list", log.Error(err))
|
r.logger.ErrorCtx(ctx, "cannot publish obligation list", log.Error(err))
|
||||||
return nil, gqlutils.Internal(ctx)
|
return nil, gqlutils.Internal(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,11 +132,14 @@ func (r *mutationResolver) PublishProcessingActivityList(ctx context.Context, in
|
|||||||
|
|
||||||
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
|
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
|
||||||
|
|
||||||
document, documentVersion, err := prb.GeneratedDocuments.PublishProcessingActivityList(ctx, input.OrganizationID, input.ApproverIds)
|
document, documentVersion, err := prb.GeneratedDocuments.PublishProcessingActivityList(ctx, input.OrganizationID, input.ApproverIds, input.Minor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
||||||
return nil, gqlutils.Conflict(ctx, err)
|
return nil, gqlutils.Conflict(ctx, err)
|
||||||
}
|
}
|
||||||
|
if errMinor, ok := errors.AsType[*probo.ErrCannotPublishMinorWithoutMajor](err); ok {
|
||||||
|
return nil, gqlutils.Invalid(ctx, errMinor)
|
||||||
|
}
|
||||||
r.logger.ErrorCtx(ctx, "cannot publish processing activity list", log.Error(err))
|
r.logger.ErrorCtx(ctx, "cannot publish processing activity list", log.Error(err))
|
||||||
return nil, gqlutils.Internal(ctx)
|
return nil, gqlutils.Internal(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -247,11 +247,14 @@ func (r *mutationResolver) PublishRiskList(ctx context.Context, input types.Publ
|
|||||||
|
|
||||||
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
|
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
|
||||||
|
|
||||||
document, documentVersion, err := prb.GeneratedDocuments.PublishRiskList(ctx, input.OrganizationID, input.ApproverIds)
|
document, documentVersion, err := prb.GeneratedDocuments.PublishRiskList(ctx, input.OrganizationID, input.ApproverIds, input.Minor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
||||||
return nil, gqlutils.Conflict(ctx, err)
|
return nil, gqlutils.Conflict(ctx, err)
|
||||||
}
|
}
|
||||||
|
if errMinor, ok := errors.AsType[*probo.ErrCannotPublishMinorWithoutMajor](err); ok {
|
||||||
|
return nil, gqlutils.Invalid(ctx, errMinor)
|
||||||
|
}
|
||||||
r.logger.ErrorCtx(ctx, "cannot publish risk list", log.Error(err))
|
r.logger.ErrorCtx(ctx, "cannot publish risk list", log.Error(err))
|
||||||
return nil, gqlutils.Internal(ctx)
|
return nil, gqlutils.Internal(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -573,11 +573,14 @@ func (r *mutationResolver) PublishVendorList(ctx context.Context, input types.Pu
|
|||||||
|
|
||||||
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
|
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
|
||||||
|
|
||||||
document, documentVersion, err := prb.GeneratedDocuments.PublishVendorList(ctx, input.OrganizationID, input.ApproverIds)
|
document, documentVersion, err := prb.GeneratedDocuments.PublishVendorList(ctx, input.OrganizationID, input.ApproverIds, input.Minor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
||||||
return nil, gqlutils.Conflict(ctx, err)
|
return nil, gqlutils.Conflict(ctx, err)
|
||||||
}
|
}
|
||||||
|
if errMinor, ok := errors.AsType[*probo.ErrCannotPublishMinorWithoutMajor](err); ok {
|
||||||
|
return nil, gqlutils.Invalid(ctx, errMinor)
|
||||||
|
}
|
||||||
r.logger.ErrorCtx(ctx, "cannot publish vendor list", log.Error(err))
|
r.logger.ErrorCtx(ctx, "cannot publish vendor list", log.Error(err))
|
||||||
return nil, gqlutils.Internal(ctx)
|
return nil, gqlutils.Internal(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3508,74 +3508,6 @@ func (r *Resolver) ListAuditLogEntriesTool(ctx context.Context, req *mcp.CallToo
|
|||||||
return nil, types.NewListAuditLogEntriesOutput(p), nil
|
return nil, types.NewListAuditLogEntriesOutput(p), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resolver) RequestDocumentVersionApprovalTool(ctx context.Context, req *mcp.CallToolRequest, input *types.RequestDocumentVersionApprovalInput) (*mcp.CallToolResult, types.RequestDocumentVersionApprovalOutput, error) {
|
|
||||||
r.MustAuthorize(ctx, input.DocumentID, probo.ActionDocumentVersionRequestApproval)
|
|
||||||
|
|
||||||
svc := r.ProboService(ctx, input.DocumentID)
|
|
||||||
|
|
||||||
quorum, err := svc.DocumentApprovals.RequestApproval(ctx, probo.RequestApprovalRequest{
|
|
||||||
DocumentID: input.DocumentID,
|
|
||||||
ApproverIDs: input.ApproverIds,
|
|
||||||
Changelog: input.Changelog,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Errorf("cannot request document version approval: %w", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
documentVersion, err := svc.Documents.GetVersion(ctx, quorum.VersionID)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Errorf("cannot get document version: %w", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, types.RequestDocumentVersionApprovalOutput{
|
|
||||||
DocumentVersion: types.NewDocumentVersion(documentVersion),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Resolver) PublishMajorDocumentVersionTool(ctx context.Context, req *mcp.CallToolRequest, input *types.PublishMajorDocumentVersionInput) (*mcp.CallToolResult, types.PublishMajorDocumentVersionOutput, error) {
|
|
||||||
r.MustAuthorize(ctx, input.DocumentID, probo.ActionDocumentVersionPublish)
|
|
||||||
|
|
||||||
svc := r.ProboService(ctx, input.DocumentID)
|
|
||||||
user := authn.IdentityFromContext(ctx)
|
|
||||||
|
|
||||||
document, documentVersion, err := svc.Documents.PublishMajorVersion(
|
|
||||||
ctx,
|
|
||||||
input.DocumentID,
|
|
||||||
user.ID,
|
|
||||||
input.Changelog,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Errorf("cannot publish major document version: %w", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, types.PublishMajorDocumentVersionOutput{
|
|
||||||
Document: types.NewDocument(document),
|
|
||||||
DocumentVersion: types.NewDocumentVersion(documentVersion),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Resolver) PublishMinorDocumentVersionTool(ctx context.Context, req *mcp.CallToolRequest, input *types.PublishMinorDocumentVersionInput) (*mcp.CallToolResult, types.PublishMinorDocumentVersionOutput, error) {
|
|
||||||
r.MustAuthorize(ctx, input.DocumentID, probo.ActionDocumentVersionPublish)
|
|
||||||
|
|
||||||
svc := r.ProboService(ctx, input.DocumentID)
|
|
||||||
user := authn.IdentityFromContext(ctx)
|
|
||||||
|
|
||||||
document, documentVersion, err := svc.Documents.PublishMinorVersion(
|
|
||||||
ctx,
|
|
||||||
input.DocumentID,
|
|
||||||
user.ID,
|
|
||||||
input.Changelog,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Errorf("cannot publish minor document version: %w", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, types.PublishMinorDocumentVersionOutput{
|
|
||||||
Document: types.NewDocument(document),
|
|
||||||
DocumentVersion: types.NewDocumentVersion(documentVersion),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Resolver) ListMeasureDocumentsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListMeasureDocumentsInput) (*mcp.CallToolResult, types.ListMeasureDocumentsOutput, error) {
|
func (r *Resolver) ListMeasureDocumentsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListMeasureDocumentsInput) (*mcp.CallToolResult, types.ListMeasureDocumentsOutput, error) {
|
||||||
r.MustAuthorize(ctx, input.MeasureID, probo.ActionMeasureGet)
|
r.MustAuthorize(ctx, input.MeasureID, probo.ActionMeasureGet)
|
||||||
|
|
||||||
@@ -3652,7 +3584,7 @@ func (r *Resolver) PublishStatementOfApplicabilityTool(ctx context.Context, req
|
|||||||
|
|
||||||
svc := r.ProboService(ctx, input.ID)
|
svc := r.ProboService(ctx, input.ID)
|
||||||
|
|
||||||
document, documentVersion, err := svc.GeneratedDocuments.PublishStatementOfApplicability(ctx, input.ID, input.ApproverIds)
|
document, documentVersion, err := svc.GeneratedDocuments.PublishStatementOfApplicability(ctx, input.ID, input.ApproverIds, input.Minor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, types.PublishStatementOfApplicabilityOutput{}, fmt.Errorf("cannot publish statement of applicability: %w", err)
|
return nil, types.PublishStatementOfApplicabilityOutput{}, fmt.Errorf("cannot publish statement of applicability: %w", err)
|
||||||
}
|
}
|
||||||
@@ -3882,7 +3814,7 @@ func (r *Resolver) PublishDataListTool(ctx context.Context, req *mcp.CallToolReq
|
|||||||
|
|
||||||
svc := r.ProboService(ctx, input.OrganizationID)
|
svc := r.ProboService(ctx, input.OrganizationID)
|
||||||
|
|
||||||
document, documentVersion, err := svc.GeneratedDocuments.PublishDataList(ctx, input.OrganizationID, input.ApproverIds)
|
document, documentVersion, err := svc.GeneratedDocuments.PublishDataList(ctx, input.OrganizationID, input.ApproverIds, input.Minor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, types.PublishDataListOutput{}, fmt.Errorf("cannot publish data list: %w", err)
|
return nil, types.PublishDataListOutput{}, fmt.Errorf("cannot publish data list: %w", err)
|
||||||
}
|
}
|
||||||
@@ -3898,7 +3830,7 @@ func (r *Resolver) PublishAssetListTool(ctx context.Context, req *mcp.CallToolRe
|
|||||||
|
|
||||||
svc := r.ProboService(ctx, input.OrganizationID)
|
svc := r.ProboService(ctx, input.OrganizationID)
|
||||||
|
|
||||||
document, documentVersion, err := svc.GeneratedDocuments.PublishAssetList(ctx, input.OrganizationID, input.ApproverIds)
|
document, documentVersion, err := svc.GeneratedDocuments.PublishAssetList(ctx, input.OrganizationID, input.ApproverIds, input.Minor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, types.PublishAssetListOutput{}, fmt.Errorf("cannot publish asset list: %w", err)
|
return nil, types.PublishAssetListOutput{}, fmt.Errorf("cannot publish asset list: %w", err)
|
||||||
}
|
}
|
||||||
@@ -4665,7 +4597,7 @@ func (r *Resolver) PublishFindingListTool(ctx context.Context, req *mcp.CallTool
|
|||||||
|
|
||||||
svc := r.ProboService(ctx, input.OrganizationID)
|
svc := r.ProboService(ctx, input.OrganizationID)
|
||||||
|
|
||||||
document, documentVersion, err := svc.GeneratedDocuments.PublishFindingList(ctx, input.OrganizationID, input.ApproverIds)
|
document, documentVersion, err := svc.GeneratedDocuments.PublishFindingList(ctx, input.OrganizationID, input.ApproverIds, input.Minor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, types.PublishFindingListOutput{}, fmt.Errorf("cannot publish finding list: %w", err)
|
return nil, types.PublishFindingListOutput{}, fmt.Errorf("cannot publish finding list: %w", err)
|
||||||
}
|
}
|
||||||
@@ -4681,7 +4613,7 @@ func (r *Resolver) PublishObligationListTool(ctx context.Context, req *mcp.CallT
|
|||||||
|
|
||||||
svc := r.ProboService(ctx, input.OrganizationID)
|
svc := r.ProboService(ctx, input.OrganizationID)
|
||||||
|
|
||||||
document, documentVersion, err := svc.GeneratedDocuments.PublishObligationList(ctx, input.OrganizationID, input.ApproverIds)
|
document, documentVersion, err := svc.GeneratedDocuments.PublishObligationList(ctx, input.OrganizationID, input.ApproverIds, input.Minor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, types.PublishObligationListOutput{}, fmt.Errorf("cannot publish obligation list: %w", err)
|
return nil, types.PublishObligationListOutput{}, fmt.Errorf("cannot publish obligation list: %w", err)
|
||||||
}
|
}
|
||||||
@@ -4697,7 +4629,7 @@ func (r *Resolver) PublishProcessingActivityListTool(ctx context.Context, req *m
|
|||||||
|
|
||||||
svc := r.ProboService(ctx, input.OrganizationID)
|
svc := r.ProboService(ctx, input.OrganizationID)
|
||||||
|
|
||||||
document, documentVersion, err := svc.GeneratedDocuments.PublishProcessingActivityList(ctx, input.OrganizationID, input.ApproverIds)
|
document, documentVersion, err := svc.GeneratedDocuments.PublishProcessingActivityList(ctx, input.OrganizationID, input.ApproverIds, input.Minor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, types.PublishProcessingActivityListOutput{}, fmt.Errorf("cannot publish processing activity list: %w", err)
|
return nil, types.PublishProcessingActivityListOutput{}, fmt.Errorf("cannot publish processing activity list: %w", err)
|
||||||
}
|
}
|
||||||
@@ -4713,7 +4645,7 @@ func (r *Resolver) PublishDataProtectionImpactAssessmentListTool(ctx context.Con
|
|||||||
|
|
||||||
svc := r.ProboService(ctx, input.OrganizationID)
|
svc := r.ProboService(ctx, input.OrganizationID)
|
||||||
|
|
||||||
document, documentVersion, err := svc.GeneratedDocuments.PublishDataProtectionImpactAssessmentList(ctx, input.OrganizationID, input.ApproverIds)
|
document, documentVersion, err := svc.GeneratedDocuments.PublishDataProtectionImpactAssessmentList(ctx, input.OrganizationID, input.ApproverIds, input.Minor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, types.PublishDataProtectionImpactAssessmentListOutput{}, fmt.Errorf("cannot publish DPIA list: %w", err)
|
return nil, types.PublishDataProtectionImpactAssessmentListOutput{}, fmt.Errorf("cannot publish DPIA list: %w", err)
|
||||||
}
|
}
|
||||||
@@ -4729,7 +4661,7 @@ func (r *Resolver) PublishTransferImpactAssessmentListTool(ctx context.Context,
|
|||||||
|
|
||||||
svc := r.ProboService(ctx, input.OrganizationID)
|
svc := r.ProboService(ctx, input.OrganizationID)
|
||||||
|
|
||||||
document, documentVersion, err := svc.GeneratedDocuments.PublishTransferImpactAssessmentList(ctx, input.OrganizationID, input.ApproverIds)
|
document, documentVersion, err := svc.GeneratedDocuments.PublishTransferImpactAssessmentList(ctx, input.OrganizationID, input.ApproverIds, input.Minor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, types.PublishTransferImpactAssessmentListOutput{}, fmt.Errorf("cannot publish TIA list: %w", err)
|
return nil, types.PublishTransferImpactAssessmentListOutput{}, fmt.Errorf("cannot publish TIA list: %w", err)
|
||||||
}
|
}
|
||||||
@@ -4745,7 +4677,7 @@ func (r *Resolver) PublishVendorListTool(ctx context.Context, req *mcp.CallToolR
|
|||||||
|
|
||||||
svc := r.ProboService(ctx, input.OrganizationID)
|
svc := r.ProboService(ctx, input.OrganizationID)
|
||||||
|
|
||||||
document, documentVersion, err := svc.GeneratedDocuments.PublishVendorList(ctx, input.OrganizationID, input.ApproverIds)
|
document, documentVersion, err := svc.GeneratedDocuments.PublishVendorList(ctx, input.OrganizationID, input.ApproverIds, input.Minor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, types.PublishVendorListOutput{}, fmt.Errorf("cannot publish vendor list: %w", err)
|
return nil, types.PublishVendorListOutput{}, fmt.Errorf("cannot publish vendor list: %w", err)
|
||||||
}
|
}
|
||||||
@@ -5098,7 +5030,7 @@ func (r *Resolver) PublishRiskListTool(ctx context.Context, req *mcp.CallToolReq
|
|||||||
|
|
||||||
svc := r.ProboService(ctx, input.OrganizationID)
|
svc := r.ProboService(ctx, input.OrganizationID)
|
||||||
|
|
||||||
document, documentVersion, err := svc.GeneratedDocuments.PublishRiskList(ctx, input.OrganizationID, input.ApproverIds)
|
document, documentVersion, err := svc.GeneratedDocuments.PublishRiskList(ctx, input.OrganizationID, input.ApproverIds, input.Minor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, types.PublishRiskListOutput{}, fmt.Errorf("cannot publish risk list: %w", err)
|
return nil, types.PublishRiskListOutput{}, fmt.Errorf("cannot publish risk list: %w", err)
|
||||||
}
|
}
|
||||||
@@ -5222,3 +5154,32 @@ func (r *Resolver) ListSCIMEventsTool(ctx context.Context, req *mcp.CallToolRequ
|
|||||||
|
|
||||||
return nil, types.NewListSCIMEventsOutput(p), nil
|
return nil, types.NewListSCIMEventsOutput(p), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Resolver) PublishDocumentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.PublishDocumentInput) (*mcp.CallToolResult, types.PublishDocumentOutput, error) {
|
||||||
|
action := probo.ActionDocumentVersionPublish
|
||||||
|
if !input.Minor && len(input.ApproverIds) > 0 {
|
||||||
|
action = probo.ActionDocumentVersionRequestApproval
|
||||||
|
}
|
||||||
|
r.MustAuthorize(ctx, input.DocumentID, action)
|
||||||
|
|
||||||
|
svc := r.ProboService(ctx, input.DocumentID)
|
||||||
|
|
||||||
|
result, err := svc.Documents.PublishVersion(ctx, probo.PublishDocumentRequest{
|
||||||
|
DocumentID: input.DocumentID,
|
||||||
|
Minor: input.Minor,
|
||||||
|
ApproverIDs: input.ApproverIds,
|
||||||
|
Changelog: input.Changelog,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Errorf("cannot publish document: %w", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
output := types.PublishDocumentOutput{
|
||||||
|
Document: types.NewDocument(result.Document),
|
||||||
|
DocumentVersion: types.NewDocumentVersion(result.Version),
|
||||||
|
}
|
||||||
|
if result.Quorum != nil {
|
||||||
|
output.ApprovalQuorum = types.NewDocumentVersionApprovalQuorum(result.Quorum)
|
||||||
|
}
|
||||||
|
return nil, output, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -5965,31 +5965,29 @@ components:
|
|||||||
document_version:
|
document_version:
|
||||||
$ref: "#/components/schemas/DocumentVersion"
|
$ref: "#/components/schemas/DocumentVersion"
|
||||||
|
|
||||||
PublishMajorDocumentVersionInput:
|
PublishDocumentInput:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- document_id
|
- document_id
|
||||||
|
- minor
|
||||||
|
- changelog
|
||||||
properties:
|
properties:
|
||||||
document_id:
|
document_id:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
description: Document ID
|
description: Document ID
|
||||||
|
minor:
|
||||||
|
type: boolean
|
||||||
|
description: When true, publish the draft as a minor version (currentMajor.currentMinor+1) and ignore approver_ids; the document must already have a published major version. When false, publish as a new major version; if approver_ids are provided, an approval is requested instead.
|
||||||
|
approver_ids:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/GID"
|
||||||
|
description: Approver profile IDs (ignored when minor is true)
|
||||||
changelog:
|
changelog:
|
||||||
type: string
|
type: string
|
||||||
description: Changelog for this version
|
description: Changelog for this version
|
||||||
|
|
||||||
PublishMinorDocumentVersionInput:
|
PublishDocumentOutput:
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- document_id
|
|
||||||
properties:
|
|
||||||
document_id:
|
|
||||||
$ref: "#/components/schemas/GID"
|
|
||||||
description: Document ID
|
|
||||||
changelog:
|
|
||||||
type: string
|
|
||||||
description: Changelog for this version
|
|
||||||
|
|
||||||
PublishDocumentVersionOutput:
|
|
||||||
type: object
|
type: object
|
||||||
description: document_version.content is markdown
|
description: document_version.content is markdown
|
||||||
required:
|
required:
|
||||||
@@ -6000,33 +5998,9 @@ components:
|
|||||||
$ref: "#/components/schemas/Document"
|
$ref: "#/components/schemas/Document"
|
||||||
document_version:
|
document_version:
|
||||||
$ref: "#/components/schemas/DocumentVersion"
|
$ref: "#/components/schemas/DocumentVersion"
|
||||||
|
approval_quorum:
|
||||||
RequestDocumentVersionApprovalInput:
|
$ref: "#/components/schemas/DocumentVersionApprovalQuorum"
|
||||||
type: object
|
description: Set when an approval was requested instead of publishing.
|
||||||
required:
|
|
||||||
- document_id
|
|
||||||
- approver_ids
|
|
||||||
properties:
|
|
||||||
document_id:
|
|
||||||
$ref: "#/components/schemas/GID"
|
|
||||||
description: Document ID
|
|
||||||
approver_ids:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: "#/components/schemas/GID"
|
|
||||||
description: Approver profile IDs
|
|
||||||
changelog:
|
|
||||||
type: string
|
|
||||||
description: Changelog for this version
|
|
||||||
|
|
||||||
RequestDocumentVersionApprovalOutput:
|
|
||||||
type: object
|
|
||||||
description: document_version.content is markdown
|
|
||||||
required:
|
|
||||||
- document_version
|
|
||||||
properties:
|
|
||||||
document_version:
|
|
||||||
$ref: "#/components/schemas/DocumentVersion"
|
|
||||||
|
|
||||||
DeleteDocumentInput:
|
DeleteDocumentInput:
|
||||||
type: object
|
type: object
|
||||||
@@ -6721,6 +6695,7 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- organization_id
|
- organization_id
|
||||||
|
- minor
|
||||||
properties:
|
properties:
|
||||||
organization_id:
|
organization_id:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
@@ -6729,7 +6704,10 @@ components:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
description: Optional approver profile IDs. If provided, creates a draft pending approval instead of publishing immediately.
|
description: Optional approver profile IDs. When minor is false and at least one ID is provided, an approval is requested as a major version. Ignored when minor is true.
|
||||||
|
minor:
|
||||||
|
type: boolean
|
||||||
|
description: When true, publish as a minor version (currentMajor.currentMinor+1) and ignore approver_ids; the document must already have a published major version. When false, publish as a new major version; if approver_ids are provided, an approval is requested instead.
|
||||||
|
|
||||||
PublishDataListOutput:
|
PublishDataListOutput:
|
||||||
type: object
|
type: object
|
||||||
@@ -6748,6 +6726,7 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- organization_id
|
- organization_id
|
||||||
|
- minor
|
||||||
properties:
|
properties:
|
||||||
organization_id:
|
organization_id:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
@@ -6756,7 +6735,10 @@ components:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
description: Optional approver profile IDs. If provided, creates a draft pending approval instead of publishing immediately.
|
description: Optional approver profile IDs. When minor is false and at least one ID is provided, an approval is requested as a major version. Ignored when minor is true.
|
||||||
|
minor:
|
||||||
|
type: boolean
|
||||||
|
description: When true, publish as a minor version (currentMajor.currentMinor+1) and ignore approver_ids; the document must already have a published major version. When false, publish as a new major version; if approver_ids are provided, an approval is requested instead.
|
||||||
|
|
||||||
PublishAssetListOutput:
|
PublishAssetListOutput:
|
||||||
type: object
|
type: object
|
||||||
@@ -6775,6 +6757,7 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- organization_id
|
- organization_id
|
||||||
|
- minor
|
||||||
properties:
|
properties:
|
||||||
organization_id:
|
organization_id:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
@@ -6783,7 +6766,10 @@ components:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
description: Optional approver profile IDs. If provided, creates a draft pending approval instead of publishing immediately.
|
description: Optional approver profile IDs. When minor is false and at least one ID is provided, an approval is requested as a major version. Ignored when minor is true.
|
||||||
|
minor:
|
||||||
|
type: boolean
|
||||||
|
description: When true, publish as a minor version (currentMajor.currentMinor+1) and ignore approver_ids; the document must already have a published major version. When false, publish as a new major version; if approver_ids are provided, an approval is requested instead.
|
||||||
|
|
||||||
PublishFindingListOutput:
|
PublishFindingListOutput:
|
||||||
type: object
|
type: object
|
||||||
@@ -6802,6 +6788,7 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- organization_id
|
- organization_id
|
||||||
|
- minor
|
||||||
properties:
|
properties:
|
||||||
organization_id:
|
organization_id:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
@@ -6810,7 +6797,10 @@ components:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
description: Optional approver profile IDs. If provided, creates a draft pending approval instead of publishing immediately.
|
description: Optional approver profile IDs. When minor is false and at least one ID is provided, an approval is requested as a major version. Ignored when minor is true.
|
||||||
|
minor:
|
||||||
|
type: boolean
|
||||||
|
description: When true, publish as a minor version (currentMajor.currentMinor+1) and ignore approver_ids; the document must already have a published major version. When false, publish as a new major version; if approver_ids are provided, an approval is requested instead.
|
||||||
|
|
||||||
PublishObligationListOutput:
|
PublishObligationListOutput:
|
||||||
type: object
|
type: object
|
||||||
@@ -6829,6 +6819,7 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- organization_id
|
- organization_id
|
||||||
|
- minor
|
||||||
properties:
|
properties:
|
||||||
organization_id:
|
organization_id:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
@@ -6837,7 +6828,10 @@ components:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
description: Optional approver profile IDs. If provided, creates a draft pending approval instead of publishing immediately.
|
description: Optional approver profile IDs. When minor is false and at least one ID is provided, an approval is requested as a major version. Ignored when minor is true.
|
||||||
|
minor:
|
||||||
|
type: boolean
|
||||||
|
description: When true, publish as a minor version (currentMajor.currentMinor+1) and ignore approver_ids; the document must already have a published major version. When false, publish as a new major version; if approver_ids are provided, an approval is requested instead.
|
||||||
|
|
||||||
PublishProcessingActivityListOutput:
|
PublishProcessingActivityListOutput:
|
||||||
type: object
|
type: object
|
||||||
@@ -6856,6 +6850,7 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- organization_id
|
- organization_id
|
||||||
|
- minor
|
||||||
properties:
|
properties:
|
||||||
organization_id:
|
organization_id:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
@@ -6864,7 +6859,10 @@ components:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
description: Optional approver profile IDs. If provided, creates a draft pending approval instead of publishing immediately.
|
description: Optional approver profile IDs. When minor is false and at least one ID is provided, an approval is requested as a major version. Ignored when minor is true.
|
||||||
|
minor:
|
||||||
|
type: boolean
|
||||||
|
description: When true, publish as a minor version (currentMajor.currentMinor+1) and ignore approver_ids; the document must already have a published major version. When false, publish as a new major version; if approver_ids are provided, an approval is requested instead.
|
||||||
|
|
||||||
PublishDataProtectionImpactAssessmentListOutput:
|
PublishDataProtectionImpactAssessmentListOutput:
|
||||||
type: object
|
type: object
|
||||||
@@ -6883,6 +6881,7 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- organization_id
|
- organization_id
|
||||||
|
- minor
|
||||||
properties:
|
properties:
|
||||||
organization_id:
|
organization_id:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
@@ -6891,7 +6890,10 @@ components:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
description: Optional approver profile IDs. If provided, creates a draft pending approval instead of publishing immediately.
|
description: Optional approver profile IDs. When minor is false and at least one ID is provided, an approval is requested as a major version. Ignored when minor is true.
|
||||||
|
minor:
|
||||||
|
type: boolean
|
||||||
|
description: When true, publish as a minor version (currentMajor.currentMinor+1) and ignore approver_ids; the document must already have a published major version. When false, publish as a new major version; if approver_ids are provided, an approval is requested instead.
|
||||||
|
|
||||||
PublishTransferImpactAssessmentListOutput:
|
PublishTransferImpactAssessmentListOutput:
|
||||||
type: object
|
type: object
|
||||||
@@ -6910,6 +6912,7 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- organization_id
|
- organization_id
|
||||||
|
- minor
|
||||||
properties:
|
properties:
|
||||||
organization_id:
|
organization_id:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
@@ -6918,7 +6921,10 @@ components:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
description: Optional approver profile IDs. If provided, creates a draft pending approval instead of publishing immediately.
|
description: Optional approver profile IDs. When minor is false and at least one ID is provided, an approval is requested as a major version. Ignored when minor is true.
|
||||||
|
minor:
|
||||||
|
type: boolean
|
||||||
|
description: When true, publish as a minor version (currentMajor.currentMinor+1) and ignore approver_ids; the document must already have a published major version. When false, publish as a new major version; if approver_ids are provided, an approval is requested instead.
|
||||||
|
|
||||||
PublishVendorListOutput:
|
PublishVendorListOutput:
|
||||||
type: object
|
type: object
|
||||||
@@ -6937,6 +6943,7 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- organization_id
|
- organization_id
|
||||||
|
- minor
|
||||||
properties:
|
properties:
|
||||||
organization_id:
|
organization_id:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
@@ -6945,7 +6952,10 @@ components:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
description: Optional approver profile IDs. If provided, creates a draft pending approval instead of publishing immediately.
|
description: Optional approver profile IDs. When minor is false and at least one ID is provided, an approval is requested as a major version. Ignored when minor is true.
|
||||||
|
minor:
|
||||||
|
type: boolean
|
||||||
|
description: When true, publish as a minor version (currentMajor.currentMinor+1) and ignore approver_ids; the document must already have a published major version. When false, publish as a new major version; if approver_ids are provided, an approval is requested instead.
|
||||||
|
|
||||||
PublishRiskListOutput:
|
PublishRiskListOutput:
|
||||||
type: object
|
type: object
|
||||||
@@ -6964,6 +6974,7 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- id
|
- id
|
||||||
|
- minor
|
||||||
properties:
|
properties:
|
||||||
id:
|
id:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
@@ -6972,7 +6983,10 @@ components:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
description: Optional approver profile IDs. If provided, creates a draft pending approval instead of publishing immediately.
|
description: Optional approver profile IDs. When minor is false and at least one ID is provided, an approval is requested as a major version. Ignored when minor is true.
|
||||||
|
minor:
|
||||||
|
type: boolean
|
||||||
|
description: When true, publish as a minor version (currentMajor.currentMinor+1) and ignore approver_ids; the document must already have a published major version. When false, publish as a new major version; if approver_ids are provided, an approval is requested instead.
|
||||||
|
|
||||||
PublishStatementOfApplicabilityOutput:
|
PublishStatementOfApplicabilityOutput:
|
||||||
type: object
|
type: object
|
||||||
@@ -11231,30 +11245,14 @@ tools:
|
|||||||
$ref: "#/components/schemas/GetDocumentVersionInput"
|
$ref: "#/components/schemas/GetDocumentVersionInput"
|
||||||
outputSchema:
|
outputSchema:
|
||||||
$ref: "#/components/schemas/GetDocumentVersionOutput"
|
$ref: "#/components/schemas/GetDocumentVersionOutput"
|
||||||
- name: publishMajorDocumentVersion
|
- name: publishDocument
|
||||||
description: Publish a draft document version as a new major version
|
description: Publish the latest draft of a document. Set minor=true to publish a minor version (no approval flow). When minor=false, providing approver_ids triggers an approval request as a new major version; otherwise the draft is published immediately as a new major version.
|
||||||
hints:
|
hints:
|
||||||
readonly: false
|
readonly: false
|
||||||
inputSchema:
|
inputSchema:
|
||||||
$ref: "#/components/schemas/PublishMajorDocumentVersionInput"
|
$ref: "#/components/schemas/PublishDocumentInput"
|
||||||
outputSchema:
|
outputSchema:
|
||||||
$ref: "#/components/schemas/PublishDocumentVersionOutput"
|
$ref: "#/components/schemas/PublishDocumentOutput"
|
||||||
- name: publishMinorDocumentVersion
|
|
||||||
description: Publish a draft document version as a minor version
|
|
||||||
hints:
|
|
||||||
readonly: false
|
|
||||||
inputSchema:
|
|
||||||
$ref: "#/components/schemas/PublishMinorDocumentVersionInput"
|
|
||||||
outputSchema:
|
|
||||||
$ref: "#/components/schemas/PublishDocumentVersionOutput"
|
|
||||||
- name: requestDocumentVersionApproval
|
|
||||||
description: Request approval for a document version
|
|
||||||
hints:
|
|
||||||
readonly: false
|
|
||||||
inputSchema:
|
|
||||||
$ref: "#/components/schemas/RequestDocumentVersionApprovalInput"
|
|
||||||
outputSchema:
|
|
||||||
$ref: "#/components/schemas/RequestDocumentVersionApprovalOutput"
|
|
||||||
- name: deleteDocument
|
- name: deleteDocument
|
||||||
description: Delete a document
|
description: Delete a document
|
||||||
hints:
|
hints:
|
||||||
|
|||||||
Reference in New Issue
Block a user