Add finding and obligation publish to document system
Replace the old snapshot-based approach with the new publish document system for findings and obligations. Includes GraphQL mutations, MCP tools, CLI commands, e2e tests, frontend publish dialogs, and snapshot-to-document migration tools. Remove snapshot mode entirely from findings and obligations: drop snapshotId from GraphQL schemas, filters, resolvers, MCP spec, frontend routes, pages, and helpers. The snapshot_id column remains in the database but is now filtered out with snapshot_id IS NULL. Remove auditor's ability to publish SoA. Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
@@ -181,10 +181,7 @@ func (r *auditResolver) Findings(ctx context.Context, obj *types.Audit, first *i
|
||||
ownerID = filter.OwnerID
|
||||
}
|
||||
|
||||
findingFilter := coredata.NewFindingFilter(nil, kind, status, priority, ownerID)
|
||||
if filter != nil {
|
||||
findingFilter = coredata.NewFindingFilter(&filter.SnapshotID, kind, status, priority, ownerID)
|
||||
}
|
||||
findingFilter := coredata.NewFindingFilter(kind, status, priority, ownerID)
|
||||
|
||||
p, err := prb.Findings.ListForAuditID(ctx, obj.ID, cursor, findingFilter)
|
||||
if err != nil {
|
||||
@@ -363,10 +360,7 @@ func (r *findingConnectionResolver) TotalCount(ctx context.Context, obj *types.F
|
||||
ownerID = obj.Filter.OwnerID
|
||||
}
|
||||
|
||||
findingFilter := coredata.NewFindingFilter(nil, kind, status, priority, ownerID)
|
||||
if obj.Filter != nil {
|
||||
findingFilter = coredata.NewFindingFilter(&obj.Filter.SnapshotID, kind, status, priority, ownerID)
|
||||
}
|
||||
findingFilter := coredata.NewFindingFilter(kind, status, priority, ownerID)
|
||||
|
||||
switch obj.Resolver.(type) {
|
||||
case *organizationResolver:
|
||||
@@ -677,6 +671,29 @@ func (r *mutationResolver) DeleteFindingAuditMapping(ctx context.Context, input
|
||||
}, nil
|
||||
}
|
||||
|
||||
// PublishFindingList is the resolver for the publishFindingList field.
|
||||
func (r *mutationResolver) PublishFindingList(ctx context.Context, input types.PublishFindingListInput) (*types.PublishFindingListPayload, error) {
|
||||
if err := r.authorize(ctx, input.OrganizationID, probo.ActionFindingPublish); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, input.OrganizationID.TenantID())
|
||||
|
||||
document, documentVersion, err := prb.GeneratedDocuments.PublishFindingList(ctx, input.OrganizationID, input.ApproverIds)
|
||||
if err != nil {
|
||||
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
||||
return nil, gqlutils.Conflict(ctx, err)
|
||||
}
|
||||
r.logger.ErrorCtx(ctx, "cannot publish finding list", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.PublishFindingListPayload{
|
||||
DocumentEdge: types.NewDocumentEdge(document, coredata.DocumentOrderFieldCreatedAt),
|
||||
DocumentVersionEdge: types.NewDocumentVersionEdge(documentVersion, coredata.DocumentVersionOrderFieldCreatedAt),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DownloadURL is the resolver for the downloadUrl field.
|
||||
func (r *reportResolver) DownloadURL(ctx context.Context, obj *types.Report) (*string, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionReportDownloadUrlGet); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user