package console_v1 // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. // Code generated by github.com/99designs/gqlgen version v0.17.73 import ( "context" "encoding/base64" "encoding/json" "errors" "fmt" "time" "github.com/getprobo/probo/pkg/coredata" "github.com/getprobo/probo/pkg/gid" "github.com/getprobo/probo/pkg/page" "github.com/getprobo/probo/pkg/probo" "github.com/getprobo/probo/pkg/server/api/console/v1/schema" "github.com/getprobo/probo/pkg/server/api/console/v1/types" "github.com/vektah/gqlparser/v2/gqlerror" ) // Owner is the resolver for the owner field. func (r *assetResolver) Owner(ctx context.Context, obj *types.Asset) (*types.People, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) asset, err := prb.Assets.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get asset: %w", err)) } owner, err := prb.Peoples.Get(ctx, asset.OwnerID) if err != nil { panic(fmt.Errorf("cannot get owner: %w", err)) } return types.NewPeople(owner), nil } // Vendors is the resolver for the vendors field. func (r *assetResolver) Vendors(ctx context.Context, obj *types.Asset, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy) (*types.VendorConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.VendorOrderField]{ Field: coredata.VendorOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.VendorOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Vendors.ListForAssetID(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list asset vendors: %w", err)) } return types.NewVendorConnection(page, r, obj.ID), nil } // AssetType is the resolver for the assetType field. func (r *assetResolver) AssetType(ctx context.Context, obj *types.Asset) (coredata.AssetType, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) asset, err := prb.Assets.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get asset: %w", err)) } return asset.AssetType, nil } // Organization is the resolver for the organization field. func (r *assetResolver) Organization(ctx context.Context, obj *types.Asset) (*types.Organization, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) if obj.Organization == nil { return nil, fmt.Errorf("cannot get organization") } org, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { return nil, fmt.Errorf("cannot get organization: %w", err) } return types.NewOrganization(org), nil } // TotalCount is the resolver for the totalCount field. func (r *assetConnectionResolver) TotalCount(ctx context.Context, obj *types.AssetConnection) (int, error) { prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: count, err := prb.Assets.CountForOrganizationID(ctx, obj.ParentID) if err != nil { return 0, fmt.Errorf("cannot count assets: %w", err) } return count, nil } panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Framework is the resolver for the framework field. func (r *controlResolver) Framework(ctx context.Context, obj *types.Control) (*types.Framework, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) control, err := prb.Controls.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get control: %w", err)) } framework, err := prb.Frameworks.Get(ctx, control.FrameworkID) if err != nil { panic(fmt.Errorf("cannot get framework: %w", err)) } return types.NewFramework(framework), nil } // Measures is the resolver for the measures field. func (r *controlResolver) Measures(ctx context.Context, obj *types.Control, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MeasureOrderBy, filter *types.MeasureFilter) (*types.MeasureConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.MeasureOrderField]{ Field: coredata.MeasureOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.MeasureOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var measureFilter = coredata.NewMeasureFilter(nil) if filter != nil { measureFilter = coredata.NewMeasureFilter(filter.Query) } page, err := prb.Measures.ListForControlID(ctx, obj.ID, cursor, measureFilter) if err != nil { return nil, fmt.Errorf("cannot list measures: %w", err) } return types.NewMeasureConnection(page, r, obj.ID, measureFilter), nil } // Documents is the resolver for the documents field. func (r *controlResolver) Documents(ctx context.Context, obj *types.Control, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy, filter *types.DocumentFilter) (*types.DocumentConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{ Field: coredata.DocumentOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.DocumentOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var documentFilter = coredata.NewDocumentFilter(nil) if filter != nil { documentFilter = coredata.NewDocumentFilter(filter.Query) } page, err := prb.Documents.ListForControlID(ctx, obj.ID, cursor, documentFilter) if err != nil { return nil, fmt.Errorf("cannot list documents: %w", err) } return types.NewDocumentConnection(page, r, obj.ID, documentFilter), nil } // TotalCount is the resolver for the totalCount field. func (r *controlConnectionResolver) TotalCount(ctx context.Context, obj *types.ControlConnection) (int, error) { prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: count, err := prb.Controls.CountForOrganizationID(ctx, obj.ParentID, obj.Filters) if err != nil { return 0, fmt.Errorf("cannot count controls: %w", err) } return count, nil case *frameworkResolver: count, err := prb.Controls.CountForFrameworkID(ctx, obj.ParentID, obj.Filters) if err != nil { return 0, fmt.Errorf("cannot count controls: %w", err) } return count, nil case *documentResolver: count, err := prb.Controls.CountForDocumentID(ctx, obj.ParentID, obj.Filters) if err != nil { return 0, fmt.Errorf("cannot count controls: %w", err) } return count, nil case *measureResolver: count, err := prb.Controls.CountForMeasureID(ctx, obj.ParentID, obj.Filters) if err != nil { return 0, fmt.Errorf("cannot count controls: %w", err) } return count, nil case *riskResolver: count, err := prb.Controls.CountForRiskID(ctx, obj.ParentID, obj.Filters) if err != nil { return 0, fmt.Errorf("cannot count controls: %w", err) } return count, nil } panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Owner is the resolver for the owner field. func (r *datumResolver) Owner(ctx context.Context, obj *types.Datum) (*types.People, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) data, err := prb.Data.Get(ctx, obj.ID) if err != nil { return nil, fmt.Errorf("cannot get datum: %w", err) } people, err := prb.Peoples.Get(ctx, data.OwnerID) if err != nil { return nil, fmt.Errorf("cannot get owner: %w", err) } return types.NewPeople(people), nil } // Vendors is the resolver for the vendors field. func (r *datumResolver) Vendors(ctx context.Context, obj *types.Datum, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy) (*types.VendorConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.VendorOrderField]{ Field: coredata.VendorOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.VendorOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Data.ListVendors(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list data vendors: %w", err)) } return types.NewVendorConnection(page, r, obj.ID), nil } // Organization is the resolver for the organization field. func (r *datumResolver) Organization(ctx context.Context, obj *types.Datum) (*types.Organization, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) org, err := prb.Organizations.Get(ctx, obj.Organization.ID) if err != nil { return nil, fmt.Errorf("cannot get organization: %w", err) } return types.NewOrganization(org), nil } // TotalCount is the resolver for the totalCount field. func (r *datumConnectionResolver) TotalCount(ctx context.Context, obj *types.DatumConnection) (int, error) { prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: count, err := prb.Data.CountForOrganizationID(ctx, obj.ParentID) if err != nil { return 0, fmt.Errorf("cannot count data: %w", err) } return count, nil } panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Owner is the resolver for the owner field. func (r *documentResolver) Owner(ctx context.Context, obj *types.Document) (*types.People, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) document, err := prb.Documents.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get document: %w", err)) } // Get the owner owner, err := prb.Peoples.Get(ctx, document.OwnerID) if err != nil { panic(fmt.Errorf("cannot get owner: %w", err)) } return types.NewPeople(owner), nil } // Organization is the resolver for the organization field. func (r *documentResolver) Organization(ctx context.Context, obj *types.Document) (*types.Organization, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) document, err := prb.Documents.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get document: %w", err)) } organization, err := prb.Organizations.Get(ctx, document.OrganizationID) if err != nil { panic(fmt.Errorf("cannot get organization: %w", err)) } return types.NewOrganization(organization), nil } // Versions is the resolver for the versions field. func (r *documentResolver) Versions(ctx context.Context, obj *types.Document, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentVersionOrderBy, filter *types.DocumentVersionFilter) (*types.DocumentVersionConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.DocumentVersionOrderField]{ Field: coredata.DocumentVersionOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.DocumentVersionOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Documents.ListVersions(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list document versions: %w", err)) } return types.NewDocumentVersionConnection(page), nil } // Controls is the resolver for the controls field. func (r *documentResolver) Controls(ctx context.Context, obj *types.Document, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.ControlOrderField]{ Field: coredata.ControlOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.ControlOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var controlFilter = coredata.NewControlFilter(nil) if filter != nil { controlFilter = coredata.NewControlFilter(filter.Query) } page, err := prb.Controls.ListForDocumentID(ctx, obj.ID, cursor, controlFilter) if err != nil { panic(fmt.Errorf("cannot list document controls: %w", err)) } return types.NewControlConnection(page, r, obj.ID, controlFilter), nil } // TotalCount is the resolver for the totalCount field. func (r *documentConnectionResolver) TotalCount(ctx context.Context, obj *types.DocumentConnection) (int, error) { prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *controlResolver: count, err := prb.Documents.CountForControlID(ctx, obj.ParentID, obj.Filters) if err != nil { return 0, fmt.Errorf("cannot count controls: %w", err) } return count, nil case *organizationResolver: count, err := prb.Documents.CountForOrganizationID(ctx, obj.ParentID, obj.Filters) if err != nil { return 0, fmt.Errorf("cannot count documents: %w", err) } return count, nil case *riskResolver: count, err := prb.Documents.CountForRiskID(ctx, obj.ParentID, obj.Filters) if err != nil { return 0, fmt.Errorf("cannot count risks: %w", err) } return count, nil } panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Document is the resolver for the document field. func (r *documentVersionResolver) Document(ctx context.Context, obj *types.DocumentVersion) (*types.Document, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) documentVersion, err := prb.Documents.GetVersion(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get document version: %w", err)) } document, err := prb.Documents.Get(ctx, documentVersion.DocumentID) if err != nil { panic(fmt.Errorf("cannot get document: %w", err)) } return types.NewDocument(document), nil } // Owner is the resolver for the owner field. func (r *documentVersionResolver) Owner(ctx context.Context, obj *types.DocumentVersion) (*types.People, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) documentVersion, err := prb.Documents.GetVersion(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get document version: %w", err)) } owner, err := prb.Peoples.Get(ctx, documentVersion.OwnerID) if err != nil { panic(fmt.Errorf("cannot get owner: %w", err)) } return types.NewPeople(owner), nil } // Signatures is the resolver for the signatures field. func (r *documentVersionResolver) Signatures(ctx context.Context, obj *types.DocumentVersion, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentVersionSignatureOrder) (*types.DocumentVersionSignatureConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.DocumentVersionSignatureOrderField]{ Field: coredata.DocumentVersionSignatureOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.DocumentVersionSignatureOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Documents.ListSignatures(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list document version signatures: %w", err)) } return types.NewDocumentVersionSignatureConnection(page), nil } // PublishedBy is the resolver for the publishedBy field. func (r *documentVersionResolver) PublishedBy(ctx context.Context, obj *types.DocumentVersion) (*types.People, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) documentVersion, err := prb.Documents.GetVersion(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get document version: %w", err)) } if documentVersion.PublishedBy == nil { return nil, nil } people, err := prb.Peoples.Get(ctx, *documentVersion.PublishedBy) if err != nil { panic(fmt.Errorf("cannot get people: %w", err)) } return types.NewPeople(people), nil } // DocumentVersion is the resolver for the documentVersion field. func (r *documentVersionSignatureResolver) DocumentVersion(ctx context.Context, obj *types.DocumentVersionSignature) (*types.DocumentVersion, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) documentVersionSignature, err := prb.Documents.GetVersionSignature(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get document version signature: %w", err)) } documentVersion, err := prb.Documents.GetVersion(ctx, documentVersionSignature.DocumentVersionID) if err != nil { panic(fmt.Errorf("cannot get document version: %w", err)) } return types.NewDocumentVersion(documentVersion), nil } // SignedBy is the resolver for the signedBy field. func (r *documentVersionSignatureResolver) SignedBy(ctx context.Context, obj *types.DocumentVersionSignature) (*types.People, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) documentVersionSignature, err := prb.Documents.GetVersionSignature(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get document version signature: %w", err)) } people, err := prb.Peoples.Get(ctx, documentVersionSignature.SignedBy) if err != nil { panic(fmt.Errorf("cannot get people: %w", err)) } return types.NewPeople(people), nil } // RequestedBy is the resolver for the requestedBy field. func (r *documentVersionSignatureResolver) RequestedBy(ctx context.Context, obj *types.DocumentVersionSignature) (*types.People, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) documentVersionSignature, err := prb.Documents.GetVersionSignature(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get document version signature: %w", err)) } people, err := prb.Peoples.Get(ctx, documentVersionSignature.RequestedBy) if err != nil { panic(fmt.Errorf("cannot get people: %w", err)) } return types.NewPeople(people), nil } // FileURL is the resolver for the fileUrl field. func (r *evidenceResolver) FileURL(ctx context.Context, obj *types.Evidence) (*string, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) if obj.Type == coredata.EvidenceTypeLink { return obj.URL, nil } fileURL, err := prb.Evidences.GenerateFileURL(ctx, obj.ID, 15*time.Minute) if err != nil { return nil, fmt.Errorf("cannot generate file URL: %w", err) } result := *fileURL return &result, nil } // Task is the resolver for the task field. func (r *evidenceResolver) Task(ctx context.Context, obj *types.Evidence) (*types.Task, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) evidence, err := prb.Evidences.Get(ctx, obj.ID) if err != nil { return nil, fmt.Errorf("cannot load evidence: %w", err) } if evidence.TaskID == nil { return nil, fmt.Errorf("evidence is not associated with a task") } task, err := prb.Tasks.Get(ctx, *evidence.TaskID) if err != nil { return nil, fmt.Errorf("cannot load task: %w", err) } return types.NewTask(task), nil } // Measure is the resolver for the measure field. func (r *evidenceResolver) Measure(ctx context.Context, obj *types.Evidence) (*types.Measure, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) evidence, err := prb.Evidences.Get(ctx, obj.ID) if err != nil { return nil, fmt.Errorf("cannot load evidence: %w", err) } measure, err := prb.Measures.Get(ctx, evidence.MeasureID) if err != nil { return nil, fmt.Errorf("cannot load measure: %w", err) } return types.NewMeasure(measure), nil } // TotalCount is the resolver for the totalCount field. func (r *evidenceConnectionResolver) TotalCount(ctx context.Context, obj *types.EvidenceConnection) (int, error) { prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *measureResolver: count, err := prb.Evidences.CountForMeasureID(ctx, obj.ParentID) if err != nil { return 0, fmt.Errorf("cannot count tasks: %w", err) } return count, nil case *taskResolver: count, err := prb.Evidences.CountForTaskID(ctx, obj.ParentID) if err != nil { return 0, fmt.Errorf("cannot count tasks: %w", err) } return count, nil } panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Organization is the resolver for the organization field. func (r *frameworkResolver) Organization(ctx context.Context, obj *types.Framework) (*types.Organization, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) framework, err := prb.Frameworks.Get(ctx, obj.ID) if err != nil { return nil, fmt.Errorf("cannot load framework: %w", err) } organization, err := prb.Organizations.Get(ctx, framework.OrganizationID) if err != nil { return nil, fmt.Errorf("cannot load organization: %w", err) } return types.NewOrganization(organization), nil } // Controls is the resolver for the controls field. func (r *frameworkResolver) Controls(ctx context.Context, obj *types.Framework, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.ControlOrderField]{ Field: coredata.ControlOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.ControlOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var controlFilter = coredata.NewControlFilter(nil) if filter != nil { controlFilter = coredata.NewControlFilter(filter.Query) } page, err := prb.Controls.ListForFrameworkID(ctx, obj.ID, cursor, controlFilter) if err != nil { return nil, fmt.Errorf("cannot list controls: %w", err) } return types.NewControlConnection(page, r, obj.ID, controlFilter), nil } // TotalCount is the resolver for the totalCount field. func (r *frameworkConnectionResolver) TotalCount(ctx context.Context, obj *types.FrameworkConnection) (int, error) { prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: count, err := prb.Frameworks.CountForOrganizationID(ctx, obj.ParentID) if err != nil { return 0, fmt.Errorf("cannot count frameworks: %w", err) } return count, nil } panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Evidences is the resolver for the evidences field. func (r *measureResolver) Evidences(ctx context.Context, obj *types.Measure, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.EvidenceOrderBy) (*types.EvidenceConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.EvidenceOrderField]{ Field: coredata.EvidenceOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.EvidenceOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Evidences.ListForMeasureID(ctx, obj.ID, cursor) if err != nil { return nil, fmt.Errorf("cannot list measure evidences: %w", err) } return types.NewEvidenceConnection(page, r, obj.ID), nil } // Tasks is the resolver for the tasks field. func (r *measureResolver) Tasks(ctx context.Context, obj *types.Measure, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TaskOrderBy) (*types.TaskConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.TaskOrderField]{ Field: coredata.TaskOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.TaskOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Tasks.ListForMeasureID(ctx, obj.ID, cursor) if err != nil { return nil, fmt.Errorf("cannot list measure tasks: %w", err) } return types.NewTaskConnection(page, r, obj.ID), nil } // Risks is the resolver for the risks field. func (r *measureResolver) Risks(ctx context.Context, obj *types.Measure, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.RiskOrderBy, filter *types.RiskFilter) (*types.RiskConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.RiskOrderField]{ Field: coredata.RiskOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.RiskOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var riskFilter = coredata.NewRiskFilter(nil) if filter != nil { riskFilter = coredata.NewRiskFilter(filter.Query) } page, err := prb.Risks.ListForMeasureID(ctx, obj.ID, cursor, riskFilter) if err != nil { return nil, fmt.Errorf("cannot list measure risks: %w", err) } return types.NewRiskConnection(page, r, obj.ID, riskFilter), nil } // Controls is the resolver for the controls field. func (r *measureResolver) Controls(ctx context.Context, obj *types.Measure, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.ControlOrderField]{ Field: coredata.ControlOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.ControlOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var controlFilter = coredata.NewControlFilter(nil) if filter != nil { controlFilter = coredata.NewControlFilter(filter.Query) } page, err := prb.Controls.ListForMeasureID(ctx, obj.ID, cursor, controlFilter) if err != nil { return nil, fmt.Errorf("cannot list measure controls: %w", err) } return types.NewControlConnection(page, r, obj.ID, controlFilter), nil } // TotalCount is the resolver for the totalCount field. func (r *measureConnectionResolver) TotalCount(ctx context.Context, obj *types.MeasureConnection) (int, error) { prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: count, err := prb.Measures.CountForOrganizationID(ctx, obj.ParentID, obj.Filters) if err != nil { return 0, fmt.Errorf("cannot count measures: %w", err) } return count, nil case *controlResolver: count, err := prb.Measures.CountForControlID(ctx, obj.ParentID, obj.Filters) if err != nil { return 0, fmt.Errorf("cannot count measures: %w", err) } return count, nil case *riskResolver: count, err := prb.Measures.CountForRiskID(ctx, obj.ParentID, obj.Filters) if err != nil { return 0, fmt.Errorf("cannot count measures: %w", err) } return count, nil } panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // CreateOrganization is the resolver for the createOrganization field. func (r *mutationResolver) CreateOrganization(ctx context.Context, input types.CreateOrganizationInput) (*types.CreateOrganizationPayload, error) { prb := r.proboSvc.WithTenant(gid.NewTenantID()) organization, err := prb.Organizations.Create( ctx, probo.CreateOrganizationRequest{ Name: input.Name, }, ) if err != nil { return nil, fmt.Errorf("cannot create organization: %w", err) } err = r.usrmgrSvc.EnrollUserInOrganization( ctx, UserFromContext(ctx).ID, organization.ID, ) if err != nil { return nil, fmt.Errorf("cannot add user to organization: %w", err) } tenantIDs, _ := ctx.Value(userTenantContextKey).(*[]gid.TenantID) *tenantIDs = append(*tenantIDs, organization.ID.TenantID()) prb = r.ProboService(ctx, organization.ID.TenantID()) _, err = prb.Peoples.Create( ctx, probo.CreatePeopleRequest{ OrganizationID: organization.ID, UserID: &UserFromContext(ctx).ID, FullName: UserFromContext(ctx).FullName, PrimaryEmailAddress: UserFromContext(ctx).EmailAddress, AdditionalEmailAddresses: []string{}, Kind: coredata.PeopleKindEmployee, }, ) if err != nil { return nil, fmt.Errorf("cannot create people: %w", err) } return &types.CreateOrganizationPayload{ OrganizationEdge: types.NewOrganizationEdge(organization, coredata.OrganizationOrderFieldCreatedAt), }, nil } // UpdateOrganization is the resolver for the updateOrganization field. func (r *mutationResolver) UpdateOrganization(ctx context.Context, input types.UpdateOrganizationInput) (*types.UpdateOrganizationPayload, error) { prb := r.ProboService(ctx, input.OrganizationID.TenantID()) req := probo.UpdateOrganizationRequest{ ID: input.OrganizationID, Name: input.Name, } if input.Logo != nil { req.File = &probo.File{ Filename: input.Logo.Filename, ContentType: input.Logo.ContentType, Size: input.Logo.Size, Content: input.Logo.File, } } organization, err := prb.Organizations.Update(ctx, req) if err != nil { return nil, fmt.Errorf("cannot update organization: %w", err) } return &types.UpdateOrganizationPayload{ Organization: types.NewOrganization(organization), }, nil } // ConfirmEmail is the resolver for the confirmEmail field. func (r *mutationResolver) ConfirmEmail(ctx context.Context, input types.ConfirmEmailInput) (*types.ConfirmEmailPayload, error) { err := r.usrmgrSvc.ConfirmEmail(ctx, input.Token) if err != nil { return nil, err } return &types.ConfirmEmailPayload{Success: true}, nil } // InviteUser is the resolver for the inviteUser field. func (r *mutationResolver) InviteUser(ctx context.Context, input types.InviteUserInput) (*types.InviteUserPayload, error) { user := UserFromContext(ctx) organizations, err := r.usrmgrSvc.ListOrganizationsForUserID(ctx, user.ID) if err != nil { panic(fmt.Errorf("failed to list organizations for user: %w", err)) } for _, organization := range organizations { if organization.ID == input.OrganizationID { err := r.usrmgrSvc.InviteUser(ctx, input.OrganizationID, input.FullName, input.Email) if err != nil { return nil, err } return &types.InviteUserPayload{Success: true}, nil } } return nil, fmt.Errorf("organization not found") } // RemoveUser is the resolver for the removeUser field. func (r *mutationResolver) RemoveUser(ctx context.Context, input types.RemoveUserInput) (*types.RemoveUserPayload, error) { user := UserFromContext(ctx) organizations, err := r.usrmgrSvc.ListOrganizationsForUserID(ctx, user.ID) if err != nil { panic(fmt.Errorf("failed to list organizations for user: %w", err)) } for _, organization := range organizations { if organization.ID == input.OrganizationID { err := r.usrmgrSvc.RemoveUser(ctx, input.OrganizationID, input.UserID) if err != nil { return nil, err } return &types.RemoveUserPayload{Success: true}, nil } } return nil, fmt.Errorf("organization not found") } // CreatePeople is the resolver for the createPeople field. func (r *mutationResolver) CreatePeople(ctx context.Context, input types.CreatePeopleInput) (*types.CreatePeoplePayload, error) { prb := r.ProboService(ctx, input.OrganizationID.TenantID()) people, err := prb.Peoples.Create(ctx, probo.CreatePeopleRequest{ OrganizationID: input.OrganizationID, FullName: input.FullName, PrimaryEmailAddress: input.PrimaryEmailAddress, AdditionalEmailAddresses: []string{}, Kind: input.Kind, Position: input.Position, ContractStartDate: input.ContractStartDate, ContractEndDate: input.ContractEndDate, }) if err != nil { return nil, fmt.Errorf("cannot create people: %w", err) } return &types.CreatePeoplePayload{ PeopleEdge: types.NewPeopleEdge(people, coredata.PeopleOrderFieldFullName), }, nil } // UpdatePeople is the resolver for the updatePeople field. func (r *mutationResolver) UpdatePeople(ctx context.Context, input types.UpdatePeopleInput) (*types.UpdatePeoplePayload, error) { prb := r.ProboService(ctx, input.ID.TenantID()) people, err := prb.Peoples.Update(ctx, probo.UpdatePeopleRequest{ ID: input.ID, FullName: input.FullName, PrimaryEmailAddress: input.PrimaryEmailAddress, AdditionalEmailAddresses: &input.AdditionalEmailAddresses, Kind: input.Kind, Position: &input.Position, ContractStartDate: &input.ContractStartDate, ContractEndDate: &input.ContractEndDate, }) if err != nil { return nil, fmt.Errorf("cannot update people: %w", err) } return &types.UpdatePeoplePayload{ People: types.NewPeople(people), }, nil } // DeletePeople is the resolver for the deletePeople field. func (r *mutationResolver) DeletePeople(ctx context.Context, input types.DeletePeopleInput) (*types.DeletePeoplePayload, error) { prb := r.ProboService(ctx, input.PeopleID.TenantID()) err := prb.Peoples.Delete(ctx, input.PeopleID) if err != nil { return nil, fmt.Errorf("cannot delete people: %w", err) } return &types.DeletePeoplePayload{ DeletedPeopleID: input.PeopleID, }, nil } // CreateVendor is the resolver for the createVendor field. func (r *mutationResolver) CreateVendor(ctx context.Context, input types.CreateVendorInput) (*types.CreateVendorPayload, error) { prb := r.ProboService(ctx, input.OrganizationID.TenantID()) vendor, err := prb.Vendors.Create( ctx, probo.CreateVendorRequest{ OrganizationID: input.OrganizationID, Name: input.Name, Description: input.Description, StatusPageURL: input.StatusPageURL, TermsOfServiceURL: input.TermsOfServiceURL, PrivacyPolicyURL: input.PrivacyPolicyURL, ServiceLevelAgreementURL: input.ServiceLevelAgreementURL, LegalName: input.LegalName, HeadquarterAddress: input.HeadquarterAddress, WebsiteURL: input.WebsiteURL, Category: input.Category, DataProcessingAgreementURL: input.DataProcessingAgreementURL, BusinessAssociateAgreementURL: input.BusinessAssociateAgreementURL, SubprocessorsListURL: input.SubprocessorsListURL, Certifications: input.Certifications, SecurityPageURL: input.SecurityPageURL, TrustPageURL: input.TrustPageURL, BusinessOwnerID: input.BusinessOwnerID, SecurityOwnerID: input.SecurityOwnerID, }, ) if err != nil { return nil, fmt.Errorf("cannot create vendor: %w", err) } return &types.CreateVendorPayload{ VendorEdge: types.NewVendorEdge(vendor, coredata.VendorOrderFieldName), }, nil } // UpdateVendor is the resolver for the updateVendor field. func (r *mutationResolver) UpdateVendor(ctx context.Context, input types.UpdateVendorInput) (*types.UpdateVendorPayload, error) { prb := r.ProboService(ctx, input.ID.TenantID()) vendor, err := prb.Vendors.Update(ctx, probo.UpdateVendorRequest{ ID: input.ID, Name: input.Name, Description: input.Description, StatusPageURL: input.StatusPageURL, TermsOfServiceURL: input.TermsOfServiceURL, PrivacyPolicyURL: input.PrivacyPolicyURL, ServiceLevelAgreementURL: input.ServiceLevelAgreementURL, DataProcessingAgreementURL: input.DataProcessingAgreementURL, BusinessAssociateAgreementURL: input.BusinessAssociateAgreementURL, SubprocessorsListURL: input.SubprocessorsListURL, SecurityPageURL: input.SecurityPageURL, TrustPageURL: input.TrustPageURL, HeadquarterAddress: input.HeadquarterAddress, LegalName: input.LegalName, WebsiteURL: input.WebsiteURL, Category: input.Category, Certifications: input.Certifications, BusinessOwnerID: input.BusinessOwnerID, SecurityOwnerID: input.SecurityOwnerID, }) if err != nil { return nil, fmt.Errorf("cannot update vendor: %w", err) } return &types.UpdateVendorPayload{ Vendor: types.NewVendor(vendor), }, nil } // DeleteVendor is the resolver for the deleteVendor field. func (r *mutationResolver) DeleteVendor(ctx context.Context, input types.DeleteVendorInput) (*types.DeleteVendorPayload, error) { prb := r.ProboService(ctx, input.VendorID.TenantID()) err := prb.Vendors.Delete(ctx, input.VendorID) if err != nil { return nil, fmt.Errorf("cannot delete vendor: %w", err) } return &types.DeleteVendorPayload{ DeletedVendorID: input.VendorID, }, nil } // CreateFramework is the resolver for the createFramework field. func (r *mutationResolver) CreateFramework(ctx context.Context, input types.CreateFrameworkInput) (*types.CreateFrameworkPayload, error) { prb := r.ProboService(ctx, input.OrganizationID.TenantID()) framework, err := prb.Frameworks.Create(ctx, probo.CreateFrameworkRequest{ OrganizationID: input.OrganizationID, Name: input.Name, }) if err != nil { return nil, fmt.Errorf("cannot create framework: %w", err) } return &types.CreateFrameworkPayload{ FrameworkEdge: types.NewFrameworkEdge(framework, coredata.FrameworkOrderFieldCreatedAt), }, nil } // UpdateFramework is the resolver for the updateFramework field. func (r *mutationResolver) UpdateFramework(ctx context.Context, input types.UpdateFrameworkInput) (*types.UpdateFrameworkPayload, error) { prb := r.ProboService(ctx, input.ID.TenantID()) framework, err := prb.Frameworks.Update(ctx, probo.UpdateFrameworkRequest{ ID: input.ID, Name: input.Name, Description: input.Description, }) if err != nil { return nil, fmt.Errorf("cannot update framework: %w", err) } return &types.UpdateFrameworkPayload{ Framework: types.NewFramework(framework), }, nil } // ImportFramework is the resolver for the importFramework field. func (r *mutationResolver) ImportFramework(ctx context.Context, input types.ImportFrameworkInput) (*types.ImportFrameworkPayload, error) { prb := r.ProboService(ctx, input.OrganizationID.TenantID()) req := probo.ImportFrameworkRequest{} if err := json.NewDecoder(input.File.File).Decode(&req.Framework); err != nil { return nil, fmt.Errorf("cannot decode framework: %w", err) } framework, err := prb.Frameworks.Import(ctx, input.OrganizationID, req) if err != nil { var errFrameworkReferenceIDAlreadyExists *coredata.ErrFrameworkReferenceIDAlreadyExists if errors.As(err, &errFrameworkReferenceIDAlreadyExists) { return nil, &gqlerror.Error{ Err: err, Message: fmt.Sprintf("framework %q already exists", req.Framework.Name), Extensions: map[string]any{ "frameworkReferenceId": errFrameworkReferenceIDAlreadyExists.ReferenceID, }, } } return nil, fmt.Errorf("cannot import framework: %w", err) } return &types.ImportFrameworkPayload{ FrameworkEdge: types.NewFrameworkEdge(framework, coredata.FrameworkOrderFieldCreatedAt), }, nil } // DeleteFramework is the resolver for the deleteFramework field. func (r *mutationResolver) DeleteFramework(ctx context.Context, input types.DeleteFrameworkInput) (*types.DeleteFrameworkPayload, error) { prb := r.ProboService(ctx, input.FrameworkID.TenantID()) err := prb.Frameworks.Delete(ctx, input.FrameworkID) if err != nil { return nil, fmt.Errorf("cannot delete framework: %w", err) } return &types.DeleteFrameworkPayload{ DeletedFrameworkID: input.FrameworkID, }, nil } // GenerateFrameworkStateOfApplicability is the resolver for the generateFrameworkStateOfApplicability field. func (r *mutationResolver) GenerateFrameworkStateOfApplicability(ctx context.Context, input types.GenerateFrameworkStateOfApplicabilityInput) (*types.GenerateFrameworkStateOfApplicabilityPayload, error) { prb := r.ProboService(ctx, input.FrameworkID.TenantID()) soa, err := prb.Frameworks.StateOfApplicability(ctx, input.FrameworkID) if err != nil { return nil, fmt.Errorf("cannot generate framework SOA: %w", err) } return &types.GenerateFrameworkStateOfApplicabilityPayload{ DownloadURL: soa, }, nil } // CreateControl is the resolver for the createControl field. func (r *mutationResolver) CreateControl(ctx context.Context, input types.CreateControlInput) (*types.CreateControlPayload, error) { prb := r.ProboService(ctx, input.FrameworkID.TenantID()) control, err := prb.Controls.Create(ctx, probo.CreateControlRequest{ FrameworkID: input.FrameworkID, Name: input.Name, Description: input.Description, SectionTitle: input.SectionTitle, }) if err != nil { return nil, fmt.Errorf("cannot create control: %w", err) } return &types.CreateControlPayload{ ControlEdge: types.NewControlEdge(control, coredata.ControlOrderFieldCreatedAt), }, nil } // UpdateControl is the resolver for the updateControl field. func (r *mutationResolver) UpdateControl(ctx context.Context, input types.UpdateControlInput) (*types.UpdateControlPayload, error) { prb := r.ProboService(ctx, input.ID.TenantID()) control, err := prb.Controls.Update(ctx, probo.UpdateControlRequest{ ID: input.ID, Name: input.Name, Description: input.Description, SectionTitle: input.SectionTitle, }) if err != nil { return nil, fmt.Errorf("cannot update control: %w", err) } return &types.UpdateControlPayload{ Control: types.NewControl(control), }, nil } // DeleteControl is the resolver for the deleteControl field. func (r *mutationResolver) DeleteControl(ctx context.Context, input types.DeleteControlInput) (*types.DeleteControlPayload, error) { prb := r.ProboService(ctx, input.ControlID.TenantID()) err := prb.Controls.Delete(ctx, input.ControlID) if err != nil { return nil, fmt.Errorf("cannot delete control: %w", err) } return &types.DeleteControlPayload{ DeletedControlID: input.ControlID, }, nil } // // CreateMeasure is the resolver for the createMeasure field. func (r *mutationResolver) CreateMeasure(ctx context.Context, input types.CreateMeasureInput) (*types.CreateMeasurePayload, error) { prb := r.ProboService(ctx, input.OrganizationID.TenantID()) measure, err := prb.Measures.Create(ctx, probo.CreateMeasureRequest{ OrganizationID: input.OrganizationID, Name: input.Name, Description: input.Description, Category: input.Category, }) if err != nil { panic(fmt.Errorf("cannot create measure: %w", err)) } return &types.CreateMeasurePayload{ MeasureEdge: types.NewMeasureEdge(measure, coredata.MeasureOrderFieldCreatedAt), }, nil } // UpdateMeasure is the resolver for the updateMeasure field. func (r *mutationResolver) UpdateMeasure(ctx context.Context, input types.UpdateMeasureInput) (*types.UpdateMeasurePayload, error) { prb := r.ProboService(ctx, input.ID.TenantID()) measure, err := prb.Measures.Update(ctx, probo.UpdateMeasureRequest{ ID: input.ID, Name: input.Name, Description: input.Description, Category: input.Category, State: input.State, }) if err != nil { panic(fmt.Errorf("cannot update measure: %w", err)) } return &types.UpdateMeasurePayload{ Measure: types.NewMeasure(measure), }, nil } // ImportMeasure is the resolver for the importMeasure field. func (r *mutationResolver) ImportMeasure(ctx context.Context, input types.ImportMeasureInput) (*types.ImportMeasurePayload, error) { prb := r.ProboService(ctx, input.OrganizationID.TenantID()) var req probo.ImportMeasureRequest if err := json.NewDecoder(input.File.File).Decode(&req.Measures); err != nil { return nil, fmt.Errorf("cannot unmarshal measure: %w", err) } measures, err := prb.Measures.Import(ctx, input.OrganizationID, req) if err != nil { return nil, fmt.Errorf("cannot import measure: %w", err) } measureEdges := make([]*types.MeasureEdge, len(measures.Data)) for i, measure := range measures.Data { measureEdges[i] = types.NewMeasureEdge(measure, coredata.MeasureOrderFieldCreatedAt) } return &types.ImportMeasurePayload{ MeasureEdges: measureEdges, }, nil } // DeleteMeasure is the resolver for the deleteMeasure field. func (r *mutationResolver) DeleteMeasure(ctx context.Context, input types.DeleteMeasureInput) (*types.DeleteMeasurePayload, error) { prb := r.ProboService(ctx, input.MeasureID.TenantID()) err := prb.Measures.Delete(ctx, input.MeasureID) if err != nil { panic(fmt.Errorf("cannot delete measure: %w", err)) } return &types.DeleteMeasurePayload{ DeletedMeasureID: input.MeasureID, }, nil } // CreateControlMeasureMapping is the resolver for the createControlMeasureMapping field. func (r *mutationResolver) CreateControlMeasureMapping(ctx context.Context, input types.CreateControlMeasureMappingInput) (*types.CreateControlMeasureMappingPayload, error) { prb := r.ProboService(ctx, input.MeasureID.TenantID()) control, measure, err := prb.Controls.CreateMeasureMapping(ctx, input.ControlID, input.MeasureID) if err != nil { panic(fmt.Errorf("cannot create control measure mapping: %w", err)) } return &types.CreateControlMeasureMappingPayload{ ControlEdge: types.NewControlEdge(control, coredata.ControlOrderFieldCreatedAt), MeasureEdge: types.NewMeasureEdge(measure, coredata.MeasureOrderFieldCreatedAt), }, nil } // CreateControlDocumentMapping is the resolver for the createControlDocumentMapping field. func (r *mutationResolver) CreateControlDocumentMapping(ctx context.Context, input types.CreateControlDocumentMappingInput) (*types.CreateControlDocumentMappingPayload, error) { prb := r.ProboService(ctx, input.DocumentID.TenantID()) control, document, err := prb.Controls.CreateDocumentMapping(ctx, input.ControlID, input.DocumentID) if err != nil { panic(fmt.Errorf("cannot create control document mapping: %w", err)) } return &types.CreateControlDocumentMappingPayload{ ControlEdge: types.NewControlEdge(control, coredata.ControlOrderFieldCreatedAt), DocumentEdge: types.NewDocumentEdge(document, coredata.DocumentOrderFieldTitle), }, nil } // DeleteControlMeasureMapping is the resolver for the deleteControlMeasureMapping field. func (r *mutationResolver) DeleteControlMeasureMapping(ctx context.Context, input types.DeleteControlMeasureMappingInput) (*types.DeleteControlMeasureMappingPayload, error) { prb := r.ProboService(ctx, input.MeasureID.TenantID()) control, measure, err := prb.Controls.DeleteMeasureMapping(ctx, input.ControlID, input.MeasureID) if err != nil { panic(fmt.Errorf("cannot delete control measure mapping: %w", err)) } return &types.DeleteControlMeasureMappingPayload{ DeletedControlID: control.ID, DeletedMeasureID: measure.ID, }, nil } // DeleteControlDocumentMapping is the resolver for the deleteControlDocumentMapping field. func (r *mutationResolver) DeleteControlDocumentMapping(ctx context.Context, input types.DeleteControlDocumentMappingInput) (*types.DeleteControlDocumentMappingPayload, error) { prb := r.ProboService(ctx, input.DocumentID.TenantID()) control, document, err := prb.Controls.DeleteDocumentMapping(ctx, input.ControlID, input.DocumentID) if err != nil { panic(fmt.Errorf("cannot delete control document mapping: %w", err)) } return &types.DeleteControlDocumentMappingPayload{ DeletedControlID: control.ID, DeletedDocumentID: document.ID, }, nil } // CreateTask is the resolver for the createTask field. func (r *mutationResolver) CreateTask(ctx context.Context, input types.CreateTaskInput) (*types.CreateTaskPayload, error) { prb := r.ProboService(ctx, input.MeasureID.TenantID()) task, err := prb.Tasks.Create(ctx, probo.CreateTaskRequest{ MeasureID: input.MeasureID, OrganizationID: input.OrganizationID, Name: input.Name, Description: input.Description, TimeEstimate: input.TimeEstimate, Deadline: input.Deadline, }) if err != nil { panic(fmt.Errorf("cannot create task: %w", err)) } return &types.CreateTaskPayload{ TaskEdge: types.NewTaskEdge(task, coredata.TaskOrderFieldCreatedAt), }, nil } // UpdateTask is the resolver for the updateTask field. func (r *mutationResolver) UpdateTask(ctx context.Context, input types.UpdateTaskInput) (*types.UpdateTaskPayload, error) { prb := r.ProboService(ctx, input.TaskID.TenantID()) task, err := prb.Tasks.Update(ctx, probo.UpdateTaskRequest{ TaskID: input.TaskID, Name: input.Name, Description: input.Description, State: input.State, TimeEstimate: input.TimeEstimate, Deadline: input.Deadline, }) if err != nil { panic(fmt.Errorf("cannot update task: %w", err)) } return &types.UpdateTaskPayload{ Task: types.NewTask(task), }, nil } // DeleteTask is the resolver for the deleteTask field. func (r *mutationResolver) DeleteTask(ctx context.Context, input types.DeleteTaskInput) (*types.DeleteTaskPayload, error) { prb := r.ProboService(ctx, input.TaskID.TenantID()) err := prb.Tasks.Delete(ctx, input.TaskID) if err != nil { panic(fmt.Errorf("cannot delete task: %w", err)) } return &types.DeleteTaskPayload{ DeletedTaskID: input.TaskID, }, nil } // AssignTask is the resolver for the assignTask field. func (r *mutationResolver) AssignTask(ctx context.Context, input types.AssignTaskInput) (*types.AssignTaskPayload, error) { prb := r.ProboService(ctx, input.TaskID.TenantID()) task, err := prb.Tasks.Assign(ctx, input.TaskID, input.AssignedToID) if err != nil { panic(fmt.Errorf("cannot assign task: %w", err)) } return &types.AssignTaskPayload{ Task: types.NewTask(task), }, nil } // UnassignTask is the resolver for the unassignTask field. func (r *mutationResolver) UnassignTask(ctx context.Context, input types.UnassignTaskInput) (*types.UnassignTaskPayload, error) { prb := r.ProboService(ctx, input.TaskID.TenantID()) task, err := prb.Tasks.Unassign(ctx, input.TaskID) if err != nil { panic(fmt.Errorf("cannot unassign task: %w", err)) } return &types.UnassignTaskPayload{ Task: types.NewTask(task), }, nil } // CreateRisk is the resolver for the createRisk field. func (r *mutationResolver) CreateRisk(ctx context.Context, input types.CreateRiskInput) (*types.CreateRiskPayload, error) { prb := r.ProboService(ctx, input.OrganizationID.TenantID()) risk, err := prb.Risks.Create( ctx, probo.CreateRiskRequest{ OrganizationID: input.OrganizationID, Name: input.Name, Description: input.Description, Category: input.Category, Treatment: input.Treatment, OwnerID: input.OwnerID, InherentLikelihood: input.InherentLikelihood, InherentImpact: input.InherentImpact, ResidualLikelihood: input.ResidualLikelihood, ResidualImpact: input.ResidualImpact, Note: input.Note, }, ) if err != nil { panic(fmt.Errorf("cannot create risk: %w", err)) } return &types.CreateRiskPayload{ RiskEdge: types.NewRiskEdge(risk, coredata.RiskOrderFieldCreatedAt), }, nil } // UpdateRisk is the resolver for the updateRisk field. func (r *mutationResolver) UpdateRisk(ctx context.Context, input types.UpdateRiskInput) (*types.UpdateRiskPayload, error) { prb := r.ProboService(ctx, input.ID.TenantID()) risk, err := prb.Risks.Update( ctx, probo.UpdateRiskRequest{ ID: input.ID, Name: input.Name, Description: input.Description, Category: input.Category, Treatment: input.Treatment, OwnerID: input.OwnerID, InherentLikelihood: input.InherentLikelihood, InherentImpact: input.InherentImpact, ResidualLikelihood: input.ResidualLikelihood, ResidualImpact: input.ResidualImpact, Note: input.Note, }, ) if err != nil { panic(fmt.Errorf("cannot update risk: %w", err)) } return &types.UpdateRiskPayload{ Risk: types.NewRisk(risk), }, nil } // DeleteRisk is the resolver for the deleteRisk field. func (r *mutationResolver) DeleteRisk(ctx context.Context, input types.DeleteRiskInput) (*types.DeleteRiskPayload, error) { prb := r.ProboService(ctx, input.RiskID.TenantID()) err := prb.Risks.Delete(ctx, input.RiskID) if err != nil { panic(fmt.Errorf("cannot delete risk: %w", err)) } return &types.DeleteRiskPayload{ DeletedRiskID: input.RiskID, }, nil } // CreateRiskMeasureMapping is the resolver for the createRiskMeasureMapping field. func (r *mutationResolver) CreateRiskMeasureMapping(ctx context.Context, input types.CreateRiskMeasureMappingInput) (*types.CreateRiskMeasureMappingPayload, error) { prb := r.ProboService(ctx, input.RiskID.TenantID()) risk, measure, err := prb.Risks.CreateMeasureMapping(ctx, input.RiskID, input.MeasureID) if err != nil { panic(fmt.Errorf("cannot create risk measure mapping: %w", err)) } return &types.CreateRiskMeasureMappingPayload{ RiskEdge: types.NewRiskEdge(risk, coredata.RiskOrderFieldCreatedAt), MeasureEdge: types.NewMeasureEdge(measure, coredata.MeasureOrderFieldCreatedAt), }, nil } // DeleteRiskMeasureMapping is the resolver for the deleteRiskMeasureMapping field. func (r *mutationResolver) DeleteRiskMeasureMapping(ctx context.Context, input types.DeleteRiskMeasureMappingInput) (*types.DeleteRiskMeasureMappingPayload, error) { prb := r.ProboService(ctx, input.RiskID.TenantID()) risk, measure, err := prb.Risks.DeleteMeasureMapping(ctx, input.RiskID, input.MeasureID) if err != nil { panic(fmt.Errorf("cannot delete risk measure mapping: %w", err)) } return &types.DeleteRiskMeasureMappingPayload{ DeletedRiskID: risk.ID, DeletedMeasureID: measure.ID, }, nil } // CreateRiskDocumentMapping is the resolver for the createRiskDocumentMapping field. func (r *mutationResolver) CreateRiskDocumentMapping(ctx context.Context, input types.CreateRiskDocumentMappingInput) (*types.CreateRiskDocumentMappingPayload, error) { prb := r.ProboService(ctx, input.RiskID.TenantID()) risk, document, err := prb.Risks.CreateDocumentMapping(ctx, input.RiskID, input.DocumentID) if err != nil { panic(fmt.Errorf("cannot create risk document mapping: %w", err)) } return &types.CreateRiskDocumentMappingPayload{ RiskEdge: types.NewRiskEdge(risk, coredata.RiskOrderFieldCreatedAt), DocumentEdge: types.NewDocumentEdge(document, coredata.DocumentOrderFieldTitle), }, nil } // DeleteRiskDocumentMapping is the resolver for the deleteRiskDocumentMapping field. func (r *mutationResolver) DeleteRiskDocumentMapping(ctx context.Context, input types.DeleteRiskDocumentMappingInput) (*types.DeleteRiskDocumentMappingPayload, error) { prb := r.ProboService(ctx, input.RiskID.TenantID()) risk, document, err := prb.Risks.DeleteDocumentMapping(ctx, input.RiskID, input.DocumentID) if err != nil { panic(fmt.Errorf("cannot delete risk document mapping: %w", err)) } return &types.DeleteRiskDocumentMappingPayload{ DeletedRiskID: risk.ID, DeletedDocumentID: document.ID, }, nil } // RequestEvidence is the resolver for the requestEvidence field. func (r *mutationResolver) RequestEvidence(ctx context.Context, input types.RequestEvidenceInput) (*types.RequestEvidencePayload, error) { prb := r.ProboService(ctx, input.TaskID.TenantID()) evidence, err := prb.Evidences.Request( ctx, probo.RequestEvidenceRequest{ TaskID: &input.TaskID, Name: input.Name, Type: input.Type, Description: input.Description, }, ) if err != nil { panic(fmt.Errorf("cannot request evidence: %w", err)) } return &types.RequestEvidencePayload{ EvidenceEdge: types.NewEvidenceEdge(evidence, coredata.EvidenceOrderFieldCreatedAt), }, nil } // FulfillEvidence is the resolver for the fulfillEvidence field. func (r *mutationResolver) FulfillEvidence(ctx context.Context, input types.FulfillEvidenceInput) (*types.FulfillEvidencePayload, error) { prb := r.ProboService(ctx, input.EvidenceID.TenantID()) req := probo.FulfilledEvidenceRequest{ EvidenceID: input.EvidenceID, } if input.File != nil { req.File = input.File.File req.Filename = &input.File.Filename } if input.URL != nil { req.URL = input.URL } evidence, err := prb.Evidences.Fulfill(ctx, req) if err != nil { panic(fmt.Errorf("cannot fulfill evidence: %w", err)) } return &types.FulfillEvidencePayload{ EvidenceEdge: types.NewEvidenceEdge(evidence, coredata.EvidenceOrderFieldCreatedAt), }, nil } // DeleteEvidence is the resolver for the deleteEvidence field. func (r *mutationResolver) DeleteEvidence(ctx context.Context, input types.DeleteEvidenceInput) (*types.DeleteEvidencePayload, error) { prb := r.ProboService(ctx, input.EvidenceID.TenantID()) err := prb.Evidences.Delete(ctx, input.EvidenceID) if err != nil { panic(fmt.Errorf("failed to delete evidence: %w", err)) } return &types.DeleteEvidencePayload{ DeletedEvidenceID: input.EvidenceID, }, nil } // UploadTaskEvidence is the resolver for the uploadTaskEvidence field. func (r *mutationResolver) UploadTaskEvidence(ctx context.Context, input types.UploadTaskEvidenceInput) (*types.UploadTaskEvidencePayload, error) { prb := r.ProboService(ctx, input.TaskID.TenantID()) evidence, err := prb.Evidences.UploadTaskEvidence( ctx, probo.UploadTaskEvidenceRequest{ TaskID: input.TaskID, File: probo.File{ Content: input.File.File, Filename: input.File.Filename, Size: input.File.Size, ContentType: input.File.ContentType, }, }, ) if err != nil { panic(fmt.Errorf("cannot upload task evidence: %w", err)) } return &types.UploadTaskEvidencePayload{ EvidenceEdge: types.NewEvidenceEdge(evidence, coredata.EvidenceOrderFieldCreatedAt), }, nil } // UploadMeasureEvidence is the resolver for the uploadMeasureEvidence field. func (r *mutationResolver) UploadMeasureEvidence(ctx context.Context, input types.UploadMeasureEvidenceInput) (*types.UploadMeasureEvidencePayload, error) { prb := r.ProboService(ctx, input.MeasureID.TenantID()) evidence, err := prb.Evidences.UploadMeasureEvidence( ctx, probo.UploadMeasureEvidenceRequest{ MeasureID: input.MeasureID, File: probo.File{ Content: input.File.File, Filename: input.File.Filename, Size: input.File.Size, ContentType: input.File.ContentType, }, }, ) if err != nil { panic(fmt.Errorf("cannot upload measure evidence: %w", err)) } return &types.UploadMeasureEvidencePayload{ EvidenceEdge: types.NewEvidenceEdge(evidence, coredata.EvidenceOrderFieldCreatedAt), }, nil } // UploadVendorComplianceReport is the resolver for the uploadVendorComplianceReport field. func (r *mutationResolver) UploadVendorComplianceReport(ctx context.Context, input types.UploadVendorComplianceReportInput) (*types.UploadVendorComplianceReportPayload, error) { prb := r.ProboService(ctx, input.VendorID.TenantID()) vendorComplianceReport, err := prb.VendorComplianceReports.Upload( ctx, input.VendorID, &probo.VendorComplianceReportCreateRequest{ File: input.File.File, ReportDate: input.ReportDate, ValidUntil: input.ValidUntil, ReportName: input.ReportName, }, ) if err != nil { panic(fmt.Errorf("failed to upload vendor compliance report: %w", err)) } return &types.UploadVendorComplianceReportPayload{ VendorComplianceReportEdge: types.NewVendorComplianceReportEdge(vendorComplianceReport, coredata.VendorComplianceReportOrderFieldCreatedAt), }, nil } // DeleteVendorComplianceReport is the resolver for the deleteVendorComplianceReport field. func (r *mutationResolver) DeleteVendorComplianceReport(ctx context.Context, input types.DeleteVendorComplianceReportInput) (*types.DeleteVendorComplianceReportPayload, error) { prb := r.ProboService(ctx, input.ReportID.TenantID()) err := prb.VendorComplianceReports.Delete(ctx, input.ReportID) if err != nil { panic(fmt.Errorf("failed to delete vendor compliance report: %w", err)) } return &types.DeleteVendorComplianceReportPayload{ DeletedVendorComplianceReportID: input.ReportID, }, nil } // CreateDocument is the resolver for the createDocument field. func (r *mutationResolver) CreateDocument(ctx context.Context, input types.CreateDocumentInput) (*types.CreateDocumentPayload, error) { prb := r.ProboService(ctx, input.OrganizationID.TenantID()) user := UserFromContext(ctx) people, err := prb.Peoples.GetByUserID(ctx, user.ID) if err != nil { panic(fmt.Errorf("cannot get people: %w", err)) } document, documentVersion, err := prb.Documents.Create( ctx, probo.CreateDocumentRequest{ OrganizationID: input.OrganizationID, DocumentType: input.DocumentType, Title: input.Title, OwnerID: input.OwnerID, Content: input.Content, CreatedBy: people.ID, }, ) if err != nil { panic(fmt.Errorf("cannot create document: %w", err)) } return &types.CreateDocumentPayload{ DocumentEdge: types.NewDocumentEdge(document, coredata.DocumentOrderFieldTitle), DocumentVersionEdge: types.NewDocumentVersionEdge(documentVersion, coredata.DocumentVersionOrderFieldCreatedAt), }, nil } // UpdateDocument is the resolver for the updateDocument field. func (r *mutationResolver) UpdateDocument(ctx context.Context, input types.UpdateDocumentInput) (*types.UpdateDocumentPayload, error) { prb := r.ProboService(ctx, input.ID.TenantID()) document, err := prb.Documents.Update( ctx, input.ID, input.OwnerID, input.DocumentType, input.Title, ) if err != nil { return nil, fmt.Errorf("cannot update document: %w", err) } return &types.UpdateDocumentPayload{ Document: types.NewDocument(document), }, nil } // DeleteDocument is the resolver for the deleteDocument field. func (r *mutationResolver) DeleteDocument(ctx context.Context, input types.DeleteDocumentInput) (*types.DeleteDocumentPayload, error) { prb := r.ProboService(ctx, input.DocumentID.TenantID()) err := prb.Documents.Delete(ctx, input.DocumentID) if err != nil { panic(fmt.Errorf("cannot delete document: %w", err)) } return &types.DeleteDocumentPayload{ DeletedDocumentID: input.DocumentID, }, nil } // PublishDocumentVersion is the resolver for the publishDocumentVersion field. func (r *mutationResolver) PublishDocumentVersion(ctx context.Context, input types.PublishDocumentVersionInput) (*types.PublishDocumentVersionPayload, error) { prb := r.ProboService(ctx, input.DocumentID.TenantID()) user := UserFromContext(ctx) people, err := prb.Peoples.GetByUserID(ctx, user.ID) if err != nil { panic(fmt.Errorf("cannot get people: %w", err)) } document, documentVersion, err := prb.Documents.PublishVersion(ctx, input.DocumentID, people.ID, input.Changelog) if err != nil { panic(fmt.Errorf("cannot publish document version: %w", err)) } return &types.PublishDocumentVersionPayload{ DocumentVersion: types.NewDocumentVersion(documentVersion), Document: types.NewDocument(document), }, nil } // GenerateDocumentChangelog is the resolver for the generateDocumentChangelog field. func (r *mutationResolver) GenerateDocumentChangelog(ctx context.Context, input types.GenerateDocumentChangelogInput) (*types.GenerateDocumentChangelogPayload, error) { prb := r.ProboService(ctx, input.DocumentID.TenantID()) changelog, err := prb.Documents.GenerateChangelog(ctx, input.DocumentID) if err != nil { panic(fmt.Errorf("cannot generate document changelog: %w", err)) } return &types.GenerateDocumentChangelogPayload{ Changelog: *changelog, }, nil } // CreateDraftDocumentVersion is the resolver for the createDraftDocumentVersion field. func (r *mutationResolver) CreateDraftDocumentVersion(ctx context.Context, input types.CreateDraftDocumentVersionInput) (*types.CreateDraftDocumentVersionPayload, error) { prb := r.ProboService(ctx, input.DocumentID.TenantID()) user := UserFromContext(ctx) people, err := prb.Peoples.GetByUserID(ctx, user.ID) if err != nil { panic(fmt.Errorf("cannot get people: %w", err)) } documentVersion, err := prb.Documents.CreateDraft(ctx, input.DocumentID, people.ID) if err != nil { panic(fmt.Errorf("cannot create draft document version: %w", err)) } return &types.CreateDraftDocumentVersionPayload{ DocumentVersionEdge: types.NewDocumentVersionEdge(documentVersion, coredata.DocumentVersionOrderFieldCreatedAt), }, nil } // UpdateDocumentVersion is the resolver for the updateDocumentVersion field. func (r *mutationResolver) UpdateDocumentVersion(ctx context.Context, input types.UpdateDocumentVersionInput) (*types.UpdateDocumentVersionPayload, error) { prb := r.ProboService(ctx, input.DocumentVersionID.TenantID()) documentVersion, err := prb.Documents.UpdateVersion(ctx, probo.UpdateDocumentVersionRequest{ ID: input.DocumentVersionID, Content: input.Content, }) if err != nil { panic(fmt.Errorf("cannot update document version: %w", err)) } return &types.UpdateDocumentVersionPayload{ DocumentVersion: types.NewDocumentVersion(documentVersion), }, nil } // RequestSignature is the resolver for the requestSignature field. func (r *mutationResolver) RequestSignature(ctx context.Context, input types.RequestSignatureInput) (*types.RequestSignaturePayload, error) { prb := r.ProboService(ctx, input.DocumentVersionID.TenantID()) user := UserFromContext(ctx) people, err := prb.Peoples.GetByUserID(ctx, user.ID) if err != nil { panic(fmt.Errorf("cannot get people: %w", err)) } documentVersionSignature, err := prb.Documents.RequestSignature( ctx, probo.RequestSignatureRequest{ DocumentVersionID: input.DocumentVersionID, RequestedBy: people.ID, Signatory: input.SignatoryID, }, ) if err != nil { panic(fmt.Errorf("cannot request signature: %w", err)) } return &types.RequestSignaturePayload{ DocumentVersionSignatureEdge: types.NewDocumentVersionSignatureEdge(documentVersionSignature, coredata.DocumentVersionSignatureOrderFieldCreatedAt), }, nil } // SendSigningNotifications is the resolver for the sendSigningNotifications field. func (r *mutationResolver) SendSigningNotifications(ctx context.Context, input types.SendSigningNotificationsInput) (*types.SendSigningNotificationsPayload, error) { prb := r.ProboService(ctx, input.OrganizationID.TenantID()) err := prb.Documents.SendSigningNotifications(ctx, input.OrganizationID) if err != nil { panic(fmt.Errorf("cannot send signing notifications: %w", err)) } return &types.SendSigningNotificationsPayload{ Success: true, }, nil } // ExportDocumentVersionPDF is the resolver for the exportDocumentVersionPDF field. func (r *mutationResolver) ExportDocumentVersionPDF(ctx context.Context, input types.ExportDocumentVersionPDFInput) (*types.ExportDocumentVersionPDFPayload, error) { prb := r.ProboService(ctx, input.DocumentVersionID.TenantID()) pdf, err := prb.Documents.ExportPDF(ctx, input.DocumentVersionID) if err != nil { panic(fmt.Errorf("cannot export document version PDF: %w", err)) } return &types.ExportDocumentVersionPDFPayload{ Data: fmt.Sprintf("data:application/pdf;base64,%s", base64.StdEncoding.EncodeToString(pdf)), }, nil } // CreateVendorRiskAssessment is the resolver for the createVendorRiskAssessment field. func (r *mutationResolver) CreateVendorRiskAssessment(ctx context.Context, input types.CreateVendorRiskAssessmentInput) (*types.CreateVendorRiskAssessmentPayload, error) { prb := r.ProboService(ctx, input.VendorID.TenantID()) vendorRiskAssessment, err := prb.Vendors.CreateRiskAssessment( ctx, probo.CreateVendorRiskAssessmentRequest{ VendorID: input.VendorID, AssessedByID: input.AssessedBy, ExpiresAt: input.ExpiresAt, DataSensitivity: input.DataSensitivity, BusinessImpact: input.BusinessImpact, Notes: input.Notes, }, ) if err != nil { panic(fmt.Errorf("cannot create vendor risk assessment: %w", err)) } return &types.CreateVendorRiskAssessmentPayload{ VendorRiskAssessmentEdge: types.NewVendorRiskAssessmentEdge(vendorRiskAssessment, coredata.VendorRiskAssessmentOrderFieldCreatedAt), }, nil } // ExportAudit is the resolver for the exportAudit field. func (r *mutationResolver) ExportAudit(ctx context.Context, input types.ExportAuditInput) (*types.ExportAuditPayload, error) { prb := r.ProboService(ctx, input.FrameworkID.TenantID()) fileUrl, err := prb.Frameworks.ExportAudit(ctx, input.FrameworkID) if err != nil { panic(fmt.Errorf("cannot export audit: %w", err)) } return &types.ExportAuditPayload{ URL: fileUrl, }, nil } // AssessVendor is the resolver for the assessVendor field. func (r *mutationResolver) AssessVendor(ctx context.Context, input types.AssessVendorInput) (*types.AssessVendorPayload, error) { prb := r.ProboService(ctx, input.ID.TenantID()) vendor, err := prb.Vendors.Assess(ctx, probo.AssessVendorRequest{ ID: input.ID, WebsiteURL: input.WebsiteURL, }) if err != nil { return nil, fmt.Errorf("cannot assess vendor: %w", err) } return &types.AssessVendorPayload{ Vendor: types.NewVendor(vendor), }, nil } // CreateAsset is the resolver for the createAsset field. func (r *mutationResolver) CreateAsset(ctx context.Context, input types.CreateAssetInput) (*types.CreateAssetPayload, error) { prb := r.ProboService(ctx, input.OrganizationID.TenantID()) asset, err := prb.Assets.Create(ctx, probo.CreateAssetRequest{ OrganizationID: input.OrganizationID, Name: input.Name, Amount: input.Amount, OwnerID: input.OwnerID, Criticity: input.Criticity, AssetType: input.AssetType, DataTypesStored: input.DataTypesStored, VendorIDs: input.VendorIds, }) if err != nil { return nil, fmt.Errorf("cannot create asset: %w", err) } return &types.CreateAssetPayload{ AssetEdge: types.NewAssetEdge(asset, coredata.AssetOrderFieldCreatedAt), }, nil } // UpdateAsset is the resolver for the updateAsset field. func (r *mutationResolver) UpdateAsset(ctx context.Context, input types.UpdateAssetInput) (*types.UpdateAssetPayload, error) { prb := r.ProboService(ctx, input.ID.TenantID()) asset, err := prb.Assets.Update(ctx, probo.UpdateAssetRequest{ ID: input.ID, Name: input.Name, Amount: input.Amount, OwnerID: input.OwnerID, Criticity: input.Criticity, AssetType: input.AssetType, DataTypesStored: input.DataTypesStored, VendorIDs: input.VendorIds, }) if err != nil { return nil, fmt.Errorf("cannot update asset: %w", err) } return &types.UpdateAssetPayload{ Asset: types.NewAsset(asset), }, nil } // DeleteAsset is the resolver for the deleteAsset field. func (r *mutationResolver) DeleteAsset(ctx context.Context, input types.DeleteAssetInput) (*types.DeleteAssetPayload, error) { prb := r.ProboService(ctx, input.AssetID.TenantID()) err := prb.Assets.Delete(ctx, input.AssetID) if err != nil { return nil, fmt.Errorf("cannot delete asset: %w", err) } return &types.DeleteAssetPayload{ DeletedAssetID: input.AssetID, }, nil } // CreateDatum is the resolver for the createDatum field. func (r *mutationResolver) CreateDatum(ctx context.Context, input types.CreateDatumInput) (*types.CreateDatumPayload, error) { prb := r.ProboService(ctx, input.OrganizationID.TenantID()) data, err := prb.Data.Create(ctx, probo.CreateDatumRequest{ OrganizationID: input.OrganizationID, Name: input.Name, DataClassification: input.DataClassification, OwnerID: input.OwnerID, VendorIDs: input.VendorIds, }) if err != nil { return nil, fmt.Errorf("cannot create datum: %w", err) } return &types.CreateDatumPayload{ DatumEdge: types.NewDatumEdge(data, coredata.DatumOrderFieldCreatedAt), }, nil } // UpdateDatum is the resolver for the updateDatum field. func (r *mutationResolver) UpdateDatum(ctx context.Context, input types.UpdateDatumInput) (*types.UpdateDatumPayload, error) { prb := r.ProboService(ctx, input.ID.TenantID()) datum, err := prb.Data.Update(ctx, probo.UpdateDatumRequest{ ID: input.ID, Name: input.Name, DataClassification: input.DataClassification, OwnerID: input.OwnerID, VendorIDs: input.VendorIds, }) if err != nil { return nil, fmt.Errorf("cannot update datum: %w", err) } return &types.UpdateDatumPayload{ Datum: types.NewDatum(datum), }, nil } // DeleteDatum is the resolver for the deleteDatum field. func (r *mutationResolver) DeleteDatum(ctx context.Context, input types.DeleteDatumInput) (*types.DeleteDatumPayload, error) { prb := r.ProboService(ctx, input.DatumID.TenantID()) if err := prb.Data.Delete(ctx, input.DatumID); err != nil { return nil, fmt.Errorf("cannot delete datum: %w", err) } return &types.DeleteDatumPayload{ DeletedDatumID: input.DatumID, }, nil } // LogoURL is the resolver for the logoUrl field. func (r *organizationResolver) LogoURL(ctx context.Context, obj *types.Organization) (*string, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) return prb.Organizations.GenerateLogoURL(ctx, obj.ID, 1*time.Hour) } // Users is the resolver for the users field. func (r *organizationResolver) Users(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.UserOrderBy) (*types.UserConnection, error) { pageOrderBy := page.OrderBy[coredata.UserOrderField]{ Field: coredata.UserOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.UserOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := r.usrmgrSvc.ListUsersForTenant(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list users: %w", err)) } return types.NewUserConnection(page), nil } // Connectors is the resolver for the connectors field. func (r *organizationResolver) Connectors(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ConnectorOrder) (*types.ConnectorConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.ConnectorOrderField]{ Field: coredata.ConnectorOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.ConnectorOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Connectors.ListForOrganizationID(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list organization connectors: %w", err)) } return types.NewConnectorConnection(page), nil } // Frameworks is the resolver for the frameworks field. func (r *organizationResolver) Frameworks(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.FrameworkOrderBy) (*types.FrameworkConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.FrameworkOrderField]{ Field: coredata.FrameworkOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.FrameworkOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Frameworks.ListForOrganizationID(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list organization frameworks: %w", err)) } return types.NewFrameworkConnection(page, r, obj.ID), nil } // Controls is the resolver for the controls field. func (r *organizationResolver) Controls(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.ControlOrderField]{ Field: coredata.ControlOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.ControlOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var controlFilter = coredata.NewControlFilter(nil) if filter != nil { controlFilter = coredata.NewControlFilter(filter.Query) } page, err := prb.Controls.ListForOrganizationID(ctx, obj.ID, cursor, controlFilter) if err != nil { return nil, fmt.Errorf("cannot list controls: %w", err) } return types.NewControlConnection(page, r, obj.ID, controlFilter), nil } // Vendors is the resolver for the vendors field. func (r *organizationResolver) Vendors(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy) (*types.VendorConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.VendorOrderField]{ Field: coredata.VendorOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.VendorOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Vendors.ListForOrganizationID(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list organization vendors: %w", err)) } return types.NewVendorConnection(page, r, obj.ID), nil } // Peoples is the resolver for the peoples field. func (r *organizationResolver) Peoples(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.PeopleOrderBy) (*types.PeopleConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.PeopleOrderField]{ Field: coredata.PeopleOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.PeopleOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Peoples.ListForOrganizationID(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list organization peoples: %w", err)) } return types.NewPeopleConnection(page, r, obj.ID), nil } // Documents is the resolver for the documents field. func (r *organizationResolver) Documents(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy, filter *types.DocumentFilter) (*types.DocumentConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{ Field: coredata.DocumentOrderFieldTitle, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.DocumentOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var documentFilter = coredata.NewDocumentFilter(nil) if filter != nil { documentFilter = coredata.NewDocumentFilter(filter.Query) } page, err := prb.Documents.ListByOrganizationID(ctx, obj.ID, cursor, documentFilter) if err != nil { panic(fmt.Errorf("cannot list organization documents: %w", err)) } return types.NewDocumentConnection(page, r, obj.ID, documentFilter), nil } // Measures is the resolver for the measures field. func (r *organizationResolver) Measures(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MeasureOrderBy, filter *types.MeasureFilter) (*types.MeasureConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.MeasureOrderField]{ Field: coredata.MeasureOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.MeasureOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var measureFilter = coredata.NewMeasureFilter(nil) if filter != nil { measureFilter = coredata.NewMeasureFilter(filter.Query) } page, err := prb.Measures.ListForOrganizationID(ctx, obj.ID, cursor, measureFilter) if err != nil { panic(fmt.Errorf("cannot list organization measures: %w", err)) } return types.NewMeasureConnection(page, r, obj.ID, measureFilter), nil } // Risks is the resolver for the risks field. func (r *organizationResolver) Risks(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.RiskOrderBy, filter *types.RiskFilter) (*types.RiskConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.RiskOrderField]{ Field: coredata.RiskOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.RiskOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var riskFilter = coredata.NewRiskFilter(nil) if filter != nil { riskFilter = coredata.NewRiskFilter(filter.Query) } page, err := prb.Risks.ListForOrganizationID(ctx, obj.ID, cursor, riskFilter) if err != nil { panic(fmt.Errorf("cannot list organization risks: %w", err)) } return types.NewRiskConnection(page, r, obj.ID, riskFilter), nil } // Tasks is the resolver for the tasks field. func (r *organizationResolver) Tasks(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TaskOrderBy) (*types.TaskConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.TaskOrderField]{ Field: coredata.TaskOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.TaskOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Tasks.ListForOrganizationID(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list organization tasks: %w", err)) } return types.NewTaskConnection(page, r, obj.ID), nil } // Assets is the resolver for the assets field. func (r *organizationResolver) Assets(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AssetOrderBy) (*types.AssetConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.AssetOrderField]{ Field: coredata.AssetOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.AssetOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Assets.ListForOrganizationID(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list organization assets: %w", err)) } return types.NewAssetConnection(page, r, obj.ID), nil } // Assets is the resolver for the assets field. func (r *organizationResolver) Data(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DatumOrderBy) (*types.DatumConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.DatumOrderField]{ Field: coredata.DatumOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.DatumOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Data.ListForOrganizationID(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("cannot list organization data: %w", err)) } return types.NewDataConnection(page, r, obj.ID), nil } // TotalCount is the resolver for the totalCount field. func (r *peopleConnectionResolver) TotalCount(ctx context.Context, obj *types.PeopleConnection) (int, error) { prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: count, err := prb.Peoples.CountForOrganizationID(ctx, obj.ParentID) if err != nil { return 0, fmt.Errorf("cannot count peoples: %w", err) } return count, nil } panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Node is the resolver for the node field. func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error) { prb := r.ProboService(ctx, id.TenantID()) switch id.EntityType() { case coredata.OrganizationEntityType: organization, err := prb.Organizations.Get(ctx, id) if err != nil { panic(fmt.Errorf("cannot get organization: %w", err)) } return types.NewOrganization(organization), nil case coredata.PeopleEntityType: people, err := prb.Peoples.Get(ctx, id) if err != nil { panic(fmt.Errorf("cannot get people: %w", err)) } return types.NewPeople(people), nil case coredata.VendorEntityType: vendor, err := prb.Vendors.Get(ctx, id) if err != nil { panic(fmt.Errorf("cannot get vendor: %w", err)) } return types.NewVendor(vendor), nil case coredata.FrameworkEntityType: framework, err := prb.Frameworks.Get(ctx, id) if err != nil { panic(fmt.Errorf("cannot get framework: %w", err)) } return types.NewFramework(framework), nil case coredata.MeasureEntityType: measure, err := prb.Measures.Get(ctx, id) if err != nil { panic(fmt.Errorf("cannot get measure: %w", err)) } return types.NewMeasure(measure), nil case coredata.TaskEntityType: task, err := prb.Tasks.Get(ctx, id) if err != nil { panic(fmt.Errorf("cannot get task: %w", err)) } return types.NewTask(task), nil case coredata.EvidenceEntityType: evidence, err := prb.Evidences.Get(ctx, id) if err != nil { panic(fmt.Errorf("cannot get evidence: %w", err)) } return types.NewEvidence(evidence), nil case coredata.DocumentEntityType: document, err := prb.Documents.Get(ctx, id) if err != nil { panic(fmt.Errorf("cannot get document: %w", err)) } return types.NewDocument(document), nil case coredata.ControlEntityType: control, err := prb.Controls.Get(ctx, id) if err != nil { panic(fmt.Errorf("cannot get control: %w", err)) } return types.NewControl(control), nil case coredata.RiskEntityType: risk, err := prb.Risks.Get(ctx, id) if err != nil { panic(fmt.Errorf("cannot get risk: %w", err)) } return types.NewRisk(risk), nil case coredata.VendorComplianceReportEntityType: vendorComplianceReport, err := prb.VendorComplianceReports.Get(ctx, id) if err != nil { panic(fmt.Errorf("cannot get vendor compliance report: %w", err)) } return types.NewVendorComplianceReport(vendorComplianceReport), nil case coredata.DocumentVersionEntityType: documentVersion, err := prb.Documents.GetVersion(ctx, id) if err != nil { panic(fmt.Errorf("cannot get document version: %w", err)) } return types.NewDocumentVersion(documentVersion), nil case coredata.DocumentVersionSignatureEntityType: documentVersionSignature, err := prb.Documents.GetVersionSignature(ctx, id) if err != nil { panic(fmt.Errorf("cannot get document version signature: %w", err)) } return types.NewDocumentVersionSignature(documentVersionSignature), nil case coredata.AssetEntityType: asset, err := prb.Assets.Get(ctx, id) if err != nil { panic(fmt.Errorf("cannot get asset: %w", err)) } return types.NewAsset(asset), nil case coredata.DatumEntityType: datum, err := prb.Data.Get(ctx, id) if err != nil { panic(fmt.Errorf("cannot get data: %w", err)) } return types.NewDatum(datum), nil default: } return nil, gqlerror.Errorf("node %q not found", id) } // Viewer is the resolver for the viewer field. func (r *queryResolver) Viewer(ctx context.Context) (*types.Viewer, error) { user := UserFromContext(ctx) session := SessionFromContext(ctx) return &types.Viewer{ ID: session.ID, User: types.NewUser(user), }, nil } // Owner is the resolver for the owner field. func (r *riskResolver) Owner(ctx context.Context, obj *types.Risk) (*types.People, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) risk, err := prb.Risks.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get risk: %w", err)) } if risk.OwnerID == nil { return nil, nil } owner, err := prb.Peoples.Get(ctx, *risk.OwnerID) if err != nil { panic(fmt.Errorf("cannot get owner: %w", err)) } return types.NewPeople(owner), nil } // Organization is the resolver for the organization field. func (r *riskResolver) Organization(ctx context.Context, obj *types.Risk) (*types.Organization, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) risk, err := prb.Risks.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get risk: %w", err)) } organization, err := prb.Organizations.Get(ctx, risk.OrganizationID) if err != nil { panic(fmt.Errorf("cannot get organization: %w", err)) } return types.NewOrganization(organization), nil } // Measures is the resolver for the measures field. func (r *riskResolver) Measures(ctx context.Context, obj *types.Risk, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MeasureOrderBy, filter *types.MeasureFilter) (*types.MeasureConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.MeasureOrderField]{ Field: coredata.MeasureOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.MeasureOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var measureFilter = coredata.NewMeasureFilter(nil) if filter != nil { measureFilter = coredata.NewMeasureFilter(filter.Query) } page, err := prb.Measures.ListForRiskID(ctx, obj.ID, cursor, measureFilter) if err != nil { panic(fmt.Errorf("cannot list risk measures: %w", err)) } return types.NewMeasureConnection(page, r, obj.ID, measureFilter), nil } // Documents is the resolver for the documents field. func (r *riskResolver) Documents(ctx context.Context, obj *types.Risk, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy, filter *types.DocumentFilter) (*types.DocumentConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{ Field: coredata.DocumentOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.DocumentOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var documentFilter = coredata.NewDocumentFilter(nil) if filter != nil { documentFilter = coredata.NewDocumentFilter(filter.Query) } page, err := prb.Documents.ListForRiskID(ctx, obj.ID, cursor, documentFilter) if err != nil { panic(fmt.Errorf("cannot list risk documents: %w", err)) } return types.NewDocumentConnection(page, r, obj.ID, documentFilter), nil } // Controls is the resolver for the controls field. func (r *riskResolver) Controls(ctx context.Context, obj *types.Risk, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.ControlOrderField]{ Field: coredata.ControlOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.ControlOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) var filters = coredata.NewControlFilter(nil) if filter != nil { filters = coredata.NewControlFilter(filter.Query) } page, err := prb.Controls.ListForRiskID(ctx, obj.ID, cursor, filters) if err != nil { panic(fmt.Errorf("cannot list risk controls: %w", err)) } return types.NewControlConnection(page, r, obj.ID, filters), nil } // TotalCount is the resolver for the totalCount field. func (r *riskConnectionResolver) TotalCount(ctx context.Context, obj *types.RiskConnection) (int, error) { prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *measureResolver: count, err := prb.Risks.CountForMeasureID(ctx, obj.ParentID, obj.Filters) if err != nil { return 0, fmt.Errorf("cannot count risks: %w", err) } return count, nil case *organizationResolver: count, err := prb.Risks.CountForOrganizationID(ctx, obj.ParentID, obj.Filters) if err != nil { return 0, fmt.Errorf("cannot count risks: %w", err) } return count, nil } panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // AssignedTo is the resolver for the assignedTo field. func (r *taskResolver) AssignedTo(ctx context.Context, obj *types.Task) (*types.People, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) task, err := prb.Tasks.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get task: %w", err)) } if task.AssignedToID == nil { return nil, nil } people, err := prb.Peoples.Get(ctx, *task.AssignedToID) if err != nil { panic(fmt.Errorf("cannot get assigned to: %w", err)) } return types.NewPeople(people), nil } // Organization is the resolver for the organization field. func (r *taskResolver) Organization(ctx context.Context, obj *types.Task) (*types.Organization, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) task, err := prb.Tasks.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get task: %w", err)) } organization, err := prb.Organizations.Get(ctx, task.OrganizationID) if err != nil { panic(fmt.Errorf("cannot get organization: %w", err)) } return types.NewOrganization(organization), nil } // Measure is the resolver for the measure field. func (r *taskResolver) Measure(ctx context.Context, obj *types.Task) (*types.Measure, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) task, err := prb.Tasks.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get task: %w", err)) } measure, err := prb.Measures.Get(ctx, *task.MeasureID) if err != nil { panic(fmt.Errorf("cannot get measure: %w", err)) } return types.NewMeasure(measure), nil } // Evidences is the resolver for the evidences field. func (r *taskResolver) Evidences(ctx context.Context, obj *types.Task, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.EvidenceOrderBy) (*types.EvidenceConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.EvidenceOrderField]{ Field: coredata.EvidenceOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.EvidenceOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Evidences.ListForTaskID(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("failed to list task evidences: %w", err)) } return types.NewEvidenceConnection(page, r, obj.ID), nil } // TotalCount is the resolver for the totalCount field. func (r *taskConnectionResolver) TotalCount(ctx context.Context, obj *types.TaskConnection) (int, error) { prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *measureResolver: count, err := prb.Tasks.CountForMeasureID(ctx, obj.ParentID) if err != nil { return 0, fmt.Errorf("cannot count tasks: %w", err) } return count, nil case *organizationResolver: count, err := prb.Tasks.CountForOrganizationID(ctx, obj.ParentID) if err != nil { return 0, fmt.Errorf("cannot count tasks: %w", err) } return count, nil } panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // People is the resolver for the people field. func (r *userResolver) People(ctx context.Context, obj *types.User, organizationID gid.GID) (*types.People, error) { prb := r.ProboService(ctx, organizationID.TenantID()) people, err := prb.Peoples.GetByUserID(ctx, obj.ID) if err != nil { panic(fmt.Errorf("failed to get people: %w", err)) } return types.NewPeople(people), nil } // Organization is the resolver for the organization field. func (r *vendorResolver) Organization(ctx context.Context, obj *types.Vendor) (*types.Organization, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) vendor, err := prb.Vendors.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("cannot get vendor: %w", err)) } organization, err := prb.Organizations.Get(ctx, vendor.OrganizationID) if err != nil { panic(fmt.Errorf("cannot get organization: %w", err)) } return types.NewOrganization(organization), nil } // ComplianceReports is the resolver for the complianceReports field. func (r *vendorResolver) ComplianceReports(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorComplianceReportOrderBy) (*types.VendorComplianceReportConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.VendorComplianceReportOrderField]{ Field: coredata.VendorComplianceReportOrderFieldReportDate, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.VendorComplianceReportOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.VendorComplianceReports.ListForVendorID(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("failed to list vendor compliance reports: %w", err)) } return types.NewVendorComplianceReportConnection(page), nil } // RiskAssessments is the resolver for the riskAssessments field. func (r *vendorResolver) RiskAssessments(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorRiskAssessmentOrder) (*types.VendorRiskAssessmentConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) pageOrderBy := page.OrderBy[coredata.VendorRiskAssessmentOrderField]{ Field: coredata.VendorRiskAssessmentOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } if orderBy != nil { pageOrderBy = page.OrderBy[coredata.VendorRiskAssessmentOrderField]{ Field: orderBy.Field, Direction: orderBy.Direction, } } cursor := types.NewCursor(first, after, last, before, pageOrderBy) page, err := prb.Vendors.ListRiskAssessments(ctx, obj.ID, cursor) if err != nil { panic(fmt.Errorf("failed to list vendor risk assessments: %w", err)) } return types.NewVendorRiskAssessmentConnection(page), nil } // BusinessOwner is the resolver for the businessOwner field. func (r *vendorResolver) BusinessOwner(ctx context.Context, obj *types.Vendor) (*types.People, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) vendor, err := prb.Vendors.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("failed to get vendor: %w", err)) } if vendor.BusinessOwnerID == nil { return nil, nil } people, err := prb.Peoples.Get(ctx, *vendor.BusinessOwnerID) if err != nil { panic(fmt.Errorf("failed to get business owner: %w", err)) } return types.NewPeople(people), nil } // SecurityOwner is the resolver for the securityOwner field. func (r *vendorResolver) SecurityOwner(ctx context.Context, obj *types.Vendor) (*types.People, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) vendor, err := prb.Vendors.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("failed to get vendor: %w", err)) } if vendor.SecurityOwnerID == nil { return nil, nil } people, err := prb.Peoples.Get(ctx, *vendor.SecurityOwnerID) if err != nil { panic(fmt.Errorf("failed to get security owner: %w", err)) } return types.NewPeople(people), nil } // Vendor is the resolver for the vendor field. func (r *vendorComplianceReportResolver) Vendor(ctx context.Context, obj *types.VendorComplianceReport) (*types.Vendor, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) vendor, err := prb.Vendors.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("failed to get vendor: %w", err)) } return types.NewVendor(vendor), nil } // FileURL is the resolver for the fileUrl field. func (r *vendorComplianceReportResolver) FileURL(ctx context.Context, obj *types.VendorComplianceReport) (string, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) fileURL, err := prb.VendorComplianceReports.GenerateFileURL(ctx, obj.ID, 1*time.Hour) if err != nil { panic(fmt.Errorf("failed to generate file URL: %w", err)) } return fileURL, nil } // TotalCount is the resolver for the totalCount field. func (r *vendorConnectionResolver) TotalCount(ctx context.Context, obj *types.VendorConnection) (int, error) { prb := r.ProboService(ctx, obj.ParentID.TenantID()) switch obj.Resolver.(type) { case *organizationResolver: count, err := prb.Vendors.CountForOrganizationID(ctx, obj.ParentID) if err != nil { return 0, fmt.Errorf("cannot count vendors: %w", err) } return count, nil case *assetResolver: count, err := prb.Vendors.CountForAssetID(ctx, obj.ParentID) if err != nil { return 0, fmt.Errorf("cannot count vendors: %w", err) } return count, nil case *datumResolver: count, err := prb.Vendors.CountForDatumID(ctx, obj.ParentID) if err != nil { return 0, fmt.Errorf("cannot count vendors: %w", err) } return count, nil } panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver)) } // Vendor is the resolver for the vendor field. func (r *vendorRiskAssessmentResolver) Vendor(ctx context.Context, obj *types.VendorRiskAssessment) (*types.Vendor, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) vendor, err := prb.Vendors.Get(ctx, obj.ID) if err != nil { panic(fmt.Errorf("failed to get vendor: %w", err)) } return types.NewVendor(vendor), nil } // AssessedBy is the resolver for the assessedBy field. func (r *vendorRiskAssessmentResolver) AssessedBy(ctx context.Context, obj *types.VendorRiskAssessment) (*types.People, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) vendorRiskAssessment, err := prb.Vendors.GetRiskAssessment(ctx, obj.ID) if err != nil { panic(fmt.Errorf("failed to get vendor risk assessment: %w", err)) } people, err := prb.Peoples.Get(ctx, vendorRiskAssessment.AssessedBy) if err != nil { panic(fmt.Errorf("failed to get assessed by: %w", err)) } return types.NewPeople(people), nil } // Organizations is the resolver for the organizations field. func (r *viewerResolver) Organizations(ctx context.Context, obj *types.Viewer, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrganizationOrder) (*types.OrganizationConnection, error) { user := UserFromContext(ctx) // For now, we're not using cursor pagination since we're loading all organizations organizations, err := r.usrmgrSvc.ListOrganizationsForUserID(ctx, user.ID) if err != nil { panic(fmt.Errorf("failed to list organizations for user: %w", err)) } var edges []*types.OrganizationEdge for _, organization := range organizations { edges = append(edges, types.NewOrganizationEdge(organization, coredata.OrganizationOrderFieldCreatedAt)) } // The simple implementation doesn't handle pagination yet return &types.OrganizationConnection{ Edges: edges, PageInfo: &types.PageInfo{ HasNextPage: false, HasPreviousPage: false, }, }, nil } // Asset returns schema.AssetResolver implementation. func (r *Resolver) Asset() schema.AssetResolver { return &assetResolver{r} } // AssetConnection returns schema.AssetConnectionResolver implementation. func (r *Resolver) AssetConnection() schema.AssetConnectionResolver { return &assetConnectionResolver{r} } // Control returns schema.ControlResolver implementation. func (r *Resolver) Control() schema.ControlResolver { return &controlResolver{r} } // ControlConnection returns schema.ControlConnectionResolver implementation. func (r *Resolver) ControlConnection() schema.ControlConnectionResolver { return &controlConnectionResolver{r} } // Datum returns schema.DatumResolver implementation. func (r *Resolver) Datum() schema.DatumResolver { return &datumResolver{r} } // DatumConnection returns schema.DatumConnectionResolver implementation. func (r *Resolver) DatumConnection() schema.DatumConnectionResolver { return &datumConnectionResolver{r} } // Document returns schema.DocumentResolver implementation. func (r *Resolver) Document() schema.DocumentResolver { return &documentResolver{r} } // DocumentConnection returns schema.DocumentConnectionResolver implementation. func (r *Resolver) DocumentConnection() schema.DocumentConnectionResolver { return &documentConnectionResolver{r} } // DocumentVersion returns schema.DocumentVersionResolver implementation. func (r *Resolver) DocumentVersion() schema.DocumentVersionResolver { return &documentVersionResolver{r} } // DocumentVersionSignature returns schema.DocumentVersionSignatureResolver implementation. func (r *Resolver) DocumentVersionSignature() schema.DocumentVersionSignatureResolver { return &documentVersionSignatureResolver{r} } // Evidence returns schema.EvidenceResolver implementation. func (r *Resolver) Evidence() schema.EvidenceResolver { return &evidenceResolver{r} } // EvidenceConnection returns schema.EvidenceConnectionResolver implementation. func (r *Resolver) EvidenceConnection() schema.EvidenceConnectionResolver { return &evidenceConnectionResolver{r} } // Framework returns schema.FrameworkResolver implementation. func (r *Resolver) Framework() schema.FrameworkResolver { return &frameworkResolver{r} } // FrameworkConnection returns schema.FrameworkConnectionResolver implementation. func (r *Resolver) FrameworkConnection() schema.FrameworkConnectionResolver { return &frameworkConnectionResolver{r} } // Measure returns schema.MeasureResolver implementation. func (r *Resolver) Measure() schema.MeasureResolver { return &measureResolver{r} } // MeasureConnection returns schema.MeasureConnectionResolver implementation. func (r *Resolver) MeasureConnection() schema.MeasureConnectionResolver { return &measureConnectionResolver{r} } // Mutation returns schema.MutationResolver implementation. func (r *Resolver) Mutation() schema.MutationResolver { return &mutationResolver{r} } // Organization returns schema.OrganizationResolver implementation. func (r *Resolver) Organization() schema.OrganizationResolver { return &organizationResolver{r} } // PeopleConnection returns schema.PeopleConnectionResolver implementation. func (r *Resolver) PeopleConnection() schema.PeopleConnectionResolver { return &peopleConnectionResolver{r} } // Query returns schema.QueryResolver implementation. func (r *Resolver) Query() schema.QueryResolver { return &queryResolver{r} } // Risk returns schema.RiskResolver implementation. func (r *Resolver) Risk() schema.RiskResolver { return &riskResolver{r} } // RiskConnection returns schema.RiskConnectionResolver implementation. func (r *Resolver) RiskConnection() schema.RiskConnectionResolver { return &riskConnectionResolver{r} } // Task returns schema.TaskResolver implementation. func (r *Resolver) Task() schema.TaskResolver { return &taskResolver{r} } // TaskConnection returns schema.TaskConnectionResolver implementation. func (r *Resolver) TaskConnection() schema.TaskConnectionResolver { return &taskConnectionResolver{r} } // User returns schema.UserResolver implementation. func (r *Resolver) User() schema.UserResolver { return &userResolver{r} } // Vendor returns schema.VendorResolver implementation. func (r *Resolver) Vendor() schema.VendorResolver { return &vendorResolver{r} } // VendorComplianceReport returns schema.VendorComplianceReportResolver implementation. func (r *Resolver) VendorComplianceReport() schema.VendorComplianceReportResolver { return &vendorComplianceReportResolver{r} } // VendorConnection returns schema.VendorConnectionResolver implementation. func (r *Resolver) VendorConnection() schema.VendorConnectionResolver { return &vendorConnectionResolver{r} } // VendorRiskAssessment returns schema.VendorRiskAssessmentResolver implementation. func (r *Resolver) VendorRiskAssessment() schema.VendorRiskAssessmentResolver { return &vendorRiskAssessmentResolver{r} } // Viewer returns schema.ViewerResolver implementation. func (r *Resolver) Viewer() schema.ViewerResolver { return &viewerResolver{r} } type assetResolver struct{ *Resolver } type assetConnectionResolver struct{ *Resolver } type controlResolver struct{ *Resolver } type controlConnectionResolver struct{ *Resolver } type datumResolver struct{ *Resolver } type datumConnectionResolver struct{ *Resolver } type documentResolver struct{ *Resolver } type documentConnectionResolver struct{ *Resolver } type documentVersionResolver struct{ *Resolver } type documentVersionSignatureResolver struct{ *Resolver } type evidenceResolver struct{ *Resolver } type evidenceConnectionResolver struct{ *Resolver } type frameworkResolver struct{ *Resolver } type frameworkConnectionResolver struct{ *Resolver } type measureResolver struct{ *Resolver } type measureConnectionResolver struct{ *Resolver } type mutationResolver struct{ *Resolver } type organizationResolver struct{ *Resolver } type peopleConnectionResolver struct{ *Resolver } type queryResolver struct{ *Resolver } type riskResolver struct{ *Resolver } type riskConnectionResolver struct{ *Resolver } type taskResolver struct{ *Resolver } type taskConnectionResolver struct{ *Resolver } type userResolver struct{ *Resolver } type vendorResolver struct{ *Resolver } type vendorComplianceReportResolver struct{ *Resolver } type vendorConnectionResolver struct{ *Resolver } type vendorRiskAssessmentResolver struct{ *Resolver } type viewerResolver struct{ *Resolver }