SOA as document: replace export with publish workflow
Statements of Applicability are no longer exported as one-off PDFs. Instead, each SOA owns a persistent document that accumulates versions over time, following the same publish/approve lifecycle as authored documents. Publishing without approvers publishes immediately; publishing with approvers creates a draft pending approval via the existing quorum system. SOAs can also store default approvers that are pre-populated in the publish dialog. The SOA is removed from the snapshot system — applicability statements are now queried directly (snapshot_id IS NULL) rather than through snapshot copies. A standalone migration script (cmd/migrate-soa-snapshots-to-documents) converts existing SOA snapshots into documents with proper ProseMirror content, preserving version history and approval decisions. Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
@@ -78,10 +78,6 @@ input ControlFilter {
|
||||
query: String
|
||||
}
|
||||
|
||||
input StatementOfApplicabilityFilter {
|
||||
snapshotId: ID
|
||||
}
|
||||
|
||||
type Control implements Node {
|
||||
id: ID!
|
||||
organization: Organization @goField(forceResolver: true)
|
||||
@@ -163,10 +159,8 @@ type ControlEdge {
|
||||
type StatementOfApplicability implements Node {
|
||||
id: ID!
|
||||
name: String!
|
||||
sourceId: ID
|
||||
snapshotId: ID
|
||||
document: Document @goField(forceResolver: true)
|
||||
organization: Organization @goField(forceResolver: true)
|
||||
owner: Profile! @goField(forceResolver: true)
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
|
||||
@@ -273,9 +267,9 @@ extend type Mutation {
|
||||
deleteStatementOfApplicability(
|
||||
input: DeleteStatementOfApplicabilityInput!
|
||||
): DeleteStatementOfApplicabilityPayload!
|
||||
exportStatementOfApplicabilityPDF(
|
||||
input: ExportStatementOfApplicabilityPDFInput!
|
||||
): ExportStatementOfApplicabilityPDFPayload!
|
||||
publishStatementOfApplicability(
|
||||
input: PublishStatementOfApplicabilityInput!
|
||||
): PublishStatementOfApplicabilityPayload!
|
||||
}
|
||||
|
||||
input CreateControlInput {
|
||||
@@ -372,13 +366,11 @@ input DeleteControlSnapshotMappingInput {
|
||||
input CreateStatementOfApplicabilityInput {
|
||||
organizationId: ID!
|
||||
name: String!
|
||||
ownerId: ID!
|
||||
}
|
||||
|
||||
input UpdateStatementOfApplicabilityInput {
|
||||
id: ID!
|
||||
name: String
|
||||
ownerId: ID
|
||||
}
|
||||
|
||||
input ApplicabilityStatementInput {
|
||||
@@ -391,8 +383,9 @@ input DeleteStatementOfApplicabilityInput {
|
||||
statementOfApplicabilityId: ID!
|
||||
}
|
||||
|
||||
input ExportStatementOfApplicabilityPDFInput {
|
||||
input PublishStatementOfApplicabilityInput {
|
||||
statementOfApplicabilityId: ID!
|
||||
approverIds: [ID!]
|
||||
}
|
||||
|
||||
type CreateControlPayload {
|
||||
@@ -481,6 +474,7 @@ type DeleteStatementOfApplicabilityPayload {
|
||||
deletedStatementOfApplicabilityId: ID!
|
||||
}
|
||||
|
||||
type ExportStatementOfApplicabilityPDFPayload {
|
||||
data: String!
|
||||
type PublishStatementOfApplicabilityPayload {
|
||||
documentEdge: DocumentEdge!
|
||||
documentVersionEdge: DocumentVersionEdge!
|
||||
}
|
||||
|
||||
@@ -37,6 +37,36 @@ enum DocumentType
|
||||
REPORT @goEnum(value: "go.probo.inc/probo/pkg/coredata.DocumentTypeReport")
|
||||
TEMPLATE
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.DocumentTypeTemplate")
|
||||
STATEMENT_OF_APPLICABILITY
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.DocumentTypeStatementOfApplicability"
|
||||
)
|
||||
}
|
||||
|
||||
enum DocumentVersionOrientation
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/coredata.DocumentVersionOrientation"
|
||||
) {
|
||||
PORTRAIT
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.DocumentVersionOrientationPortrait"
|
||||
)
|
||||
LANDSCAPE
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.DocumentVersionOrientationLandscape"
|
||||
)
|
||||
}
|
||||
|
||||
enum DocumentWriteMode
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.DocumentWriteMode") {
|
||||
AUTHORED
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.DocumentWriteModeAuthored"
|
||||
)
|
||||
GENERATED
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.DocumentWriteModeGenerated"
|
||||
)
|
||||
}
|
||||
|
||||
enum DocumentClassification
|
||||
@@ -199,6 +229,7 @@ input DocumentVersionOrder
|
||||
|
||||
input DocumentFilter {
|
||||
query: String
|
||||
writeModes: [DocumentWriteMode!]
|
||||
documentTypes: [DocumentType!]
|
||||
classifications: [DocumentClassification!]
|
||||
status: [DocumentStatus!]
|
||||
@@ -259,6 +290,7 @@ type Document implements Node {
|
||||
|
||||
defaultApprovers: [Profile!]! @goField(forceResolver: true)
|
||||
|
||||
writeMode: DocumentWriteMode!
|
||||
status: DocumentStatus!
|
||||
archivedAt: Datetime
|
||||
|
||||
@@ -279,6 +311,7 @@ type DocumentVersion implements Node {
|
||||
title: String!
|
||||
classification: DocumentClassification!
|
||||
documentType: DocumentType!
|
||||
orientation: DocumentVersionOrientation!
|
||||
approvers(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
|
||||
@@ -60,6 +60,10 @@ enum ElectronicSignatureDocumentType
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.ElectronicSignatureDocumentTypeOther"
|
||||
)
|
||||
STATEMENT_OF_APPLICABILITY
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.ElectronicSignatureDocumentTypeStatementOfApplicability"
|
||||
)
|
||||
}
|
||||
|
||||
enum ElectronicSignatureEventType
|
||||
|
||||
@@ -190,7 +190,6 @@ type Organization implements Node {
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: StatementOfApplicabilityOrder
|
||||
filter: StatementOfApplicabilityFilter = { snapshotId: null }
|
||||
): StatementOfApplicabilityConnection! @goField(forceResolver: true)
|
||||
|
||||
dataProtectionImpactAssessments(
|
||||
|
||||
Reference in New Issue
Block a user