Add document archiving
Documents can be archived and unarchived. Archived documents are read-only, excluded from the trust center, and moved to a dedicated Archived tab in the document list. - Add archived_at timestamp and status (ACTIVE/ARCHIVED) PG enum column - Rename DocumentStatus → DocumentVersionStatus, introduce DocumentStatus - Archive/unarchive mutations in GraphQL, MCP, and CLI - Bulk archive/unarchive mutations with Active/Archived tabs in the list - ABAC policies: write actions denied on archived docs, unarchive denied on active docs - Remove control/risk mappings and reset trust center visibility on archive - Exclude archived documents from mapping dialogs and trust center tab Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
@@ -799,7 +799,7 @@ func (r *Resolver) AddFindingTool(ctx context.Context, req *mcp.CallToolRequest,
|
||||
Kind: input.Kind,
|
||||
Description: input.Description,
|
||||
Source: input.Source,
|
||||
IdentifiedOn: input.IdentifiedOn,
|
||||
IdentifiedOn: input.IdentifiedOn,
|
||||
RootCause: input.RootCause,
|
||||
CorrectiveAction: input.CorrectiveAction,
|
||||
OwnerID: input.OwnerID,
|
||||
@@ -830,7 +830,7 @@ func (r *Resolver) UpdateFindingTool(ctx context.Context, req *mcp.CallToolReque
|
||||
ID: input.ID,
|
||||
Description: UnwrapOmittable(input.Description),
|
||||
Source: UnwrapOmittable(input.Source),
|
||||
IdentifiedOn: UnwrapOmittable(input.IdentifiedOn),
|
||||
IdentifiedOn: UnwrapOmittable(input.IdentifiedOn),
|
||||
RootCause: UnwrapOmittable(input.RootCause),
|
||||
CorrectiveAction: UnwrapOmittable(input.CorrectiveAction),
|
||||
OwnerID: input.OwnerID,
|
||||
@@ -3201,3 +3201,43 @@ func (r *Resolver) ListFindingAuditsTool(ctx context.Context, req *mcp.CallToolR
|
||||
|
||||
return nil, types.NewListFindingAuditsOutput(auditPage), nil
|
||||
}
|
||||
|
||||
func (r *Resolver) ArchiveDocumentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ArchiveDocumentInput) (*mcp.CallToolResult, types.ArchiveDocumentOutput, error) {
|
||||
r.MustAuthorize(ctx, input.ID, probo.ActionDocumentArchive)
|
||||
|
||||
svc := r.ProboService(ctx, input.ID)
|
||||
|
||||
document, err := svc.Documents.Archive(ctx, input.ID)
|
||||
if err != nil {
|
||||
return nil, types.ArchiveDocumentOutput{}, fmt.Errorf("cannot archive document: %w", err)
|
||||
}
|
||||
|
||||
approverPage, err := svc.Documents.ListApprovers(ctx, input.ID, allApproversCursor())
|
||||
if err != nil {
|
||||
return nil, types.ArchiveDocumentOutput{}, fmt.Errorf("cannot list document approvers: %w", err)
|
||||
}
|
||||
|
||||
return nil, types.ArchiveDocumentOutput{
|
||||
Document: types.NewDocument(document, profileIDs(approverPage)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *Resolver) UnarchiveDocumentTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UnarchiveDocumentInput) (*mcp.CallToolResult, types.UnarchiveDocumentOutput, error) {
|
||||
r.MustAuthorize(ctx, input.ID, probo.ActionDocumentUnarchive)
|
||||
|
||||
svc := r.ProboService(ctx, input.ID)
|
||||
|
||||
document, err := svc.Documents.Unarchive(ctx, input.ID)
|
||||
if err != nil {
|
||||
return nil, types.UnarchiveDocumentOutput{}, fmt.Errorf("cannot unarchive document: %w", err)
|
||||
}
|
||||
|
||||
approverPage, err := svc.Documents.ListApprovers(ctx, input.ID, allApproversCursor())
|
||||
if err != nil {
|
||||
return nil, types.UnarchiveDocumentOutput{}, fmt.Errorf("cannot list document approvers: %w", err)
|
||||
}
|
||||
|
||||
return nil, types.UnarchiveDocumentOutput{
|
||||
Document: types.NewDocument(document, profileIDs(approverPage)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -5057,11 +5057,18 @@ components:
|
||||
- SECRET
|
||||
go.probo.inc/mcpgen/type: go.probo.inc/probo/pkg/coredata.DocumentClassification
|
||||
|
||||
DocumentStatus:
|
||||
DocumentVersionStatus:
|
||||
type: string
|
||||
enum:
|
||||
- DRAFT
|
||||
- PUBLISHED
|
||||
go.probo.inc/mcpgen/type: go.probo.inc/probo/pkg/coredata.DocumentVersionStatus
|
||||
|
||||
DocumentStatus:
|
||||
type: string
|
||||
enum:
|
||||
- ACTIVE
|
||||
- ARCHIVED
|
||||
go.probo.inc/mcpgen/type: go.probo.inc/probo/pkg/coredata.DocumentStatus
|
||||
|
||||
DocumentVersionSignatureState:
|
||||
@@ -5142,6 +5149,7 @@ components:
|
||||
- document_type
|
||||
- classification
|
||||
- trust_center_visibility
|
||||
- status
|
||||
- created_at
|
||||
- updated_at
|
||||
properties:
|
||||
@@ -5173,6 +5181,15 @@ components:
|
||||
trust_center_visibility:
|
||||
$ref: "#/components/schemas/TrustCenterVisibility"
|
||||
description: Trust center visibility
|
||||
status:
|
||||
$ref: "#/components/schemas/DocumentStatus"
|
||||
description: Document status
|
||||
archived_at:
|
||||
type:
|
||||
- string
|
||||
- "null"
|
||||
format: date-time
|
||||
description: Archive timestamp
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
@@ -5228,8 +5245,8 @@ components:
|
||||
type: string
|
||||
description: Changelog
|
||||
status:
|
||||
$ref: "#/components/schemas/DocumentStatus"
|
||||
description: Document status
|
||||
$ref: "#/components/schemas/DocumentVersionStatus"
|
||||
description: Document version status
|
||||
published_at:
|
||||
type:
|
||||
- string
|
||||
@@ -5434,6 +5451,40 @@ components:
|
||||
document:
|
||||
$ref: "#/components/schemas/Document"
|
||||
|
||||
ArchiveDocumentInput:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
properties:
|
||||
id:
|
||||
$ref: "#/components/schemas/GID"
|
||||
description: Document ID
|
||||
|
||||
ArchiveDocumentOutput:
|
||||
type: object
|
||||
required:
|
||||
- document
|
||||
properties:
|
||||
document:
|
||||
$ref: "#/components/schemas/Document"
|
||||
|
||||
UnarchiveDocumentInput:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
properties:
|
||||
id:
|
||||
$ref: "#/components/schemas/GID"
|
||||
description: Document ID
|
||||
|
||||
UnarchiveDocumentOutput:
|
||||
type: object
|
||||
required:
|
||||
- document
|
||||
properties:
|
||||
document:
|
||||
$ref: "#/components/schemas/Document"
|
||||
|
||||
ListDocumentVersionsInput:
|
||||
type: object
|
||||
required:
|
||||
@@ -7133,6 +7184,22 @@ tools:
|
||||
$ref: "#/components/schemas/UpdateDocumentInput"
|
||||
outputSchema:
|
||||
$ref: "#/components/schemas/UpdateDocumentOutput"
|
||||
- name: archiveDocument
|
||||
description: Archive a document to prevent further modifications
|
||||
hints:
|
||||
readonly: false
|
||||
inputSchema:
|
||||
$ref: "#/components/schemas/ArchiveDocumentInput"
|
||||
outputSchema:
|
||||
$ref: "#/components/schemas/ArchiveDocumentOutput"
|
||||
- name: unarchiveDocument
|
||||
description: Unarchive a document to allow modifications again
|
||||
hints:
|
||||
readonly: false
|
||||
inputSchema:
|
||||
$ref: "#/components/schemas/UnarchiveDocumentInput"
|
||||
outputSchema:
|
||||
$ref: "#/components/schemas/UnarchiveDocumentOutput"
|
||||
- name: listDocumentVersions
|
||||
description: List all versions for a document
|
||||
hints:
|
||||
|
||||
@@ -30,6 +30,8 @@ func NewDocument(d *coredata.Document, approverIDs []gid.GID) *Document {
|
||||
Classification: d.Classification,
|
||||
CurrentPublishedVersion: d.CurrentPublishedVersion,
|
||||
TrustCenterVisibility: d.TrustCenterVisibility,
|
||||
Status: d.Status,
|
||||
ArchivedAt: d.ArchivedAt,
|
||||
CreatedAt: d.CreatedAt,
|
||||
UpdatedAt: d.UpdatedAt,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user