@@ -461,6 +461,14 @@ type Organization implements Node {
|
||||
orderBy: RiskOrder
|
||||
): RiskConnection! @goField(forceResolver: true)
|
||||
|
||||
tasks(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: TaskOrder
|
||||
): TaskConnection! @goField(forceResolver: true)
|
||||
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
}
|
||||
@@ -498,6 +506,8 @@ type Vendor implements Node {
|
||||
name: String!
|
||||
description: String
|
||||
|
||||
organization: Organization! @goField(forceResolver: true)
|
||||
|
||||
complianceReports(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
@@ -538,10 +548,8 @@ type VendorComplianceReport implements Node {
|
||||
reportDate: Datetime!
|
||||
validUntil: Datetime
|
||||
reportName: String!
|
||||
|
||||
fileUrl: String! @goField(forceResolver: true)
|
||||
fileSize: Int!
|
||||
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
}
|
||||
@@ -551,6 +559,8 @@ type Framework implements Node {
|
||||
name: String!
|
||||
description: String!
|
||||
|
||||
organization: Organization! @goField(forceResolver: true)
|
||||
|
||||
controls(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
@@ -569,6 +579,8 @@ type Control implements Node {
|
||||
name: String!
|
||||
description: String!
|
||||
|
||||
framework: Framework! @goField(forceResolver: true)
|
||||
|
||||
measures(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
@@ -640,6 +652,9 @@ type Task implements Node {
|
||||
timeEstimate: Duration
|
||||
assignedTo: People @goField(forceResolver: true)
|
||||
|
||||
organization: Organization! @goField(forceResolver: true)
|
||||
measure: Measure @goField(forceResolver: true)
|
||||
|
||||
evidences(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
@@ -663,6 +678,9 @@ type Evidence implements Node {
|
||||
url: String
|
||||
description: String!
|
||||
|
||||
task: Task @goField(forceResolver: true)
|
||||
measure: Measure! @goField(forceResolver: true)
|
||||
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
}
|
||||
@@ -673,6 +691,7 @@ type Policy implements Node {
|
||||
description: String!
|
||||
currentPublishedVersion: Int
|
||||
owner: People! @goField(forceResolver: true)
|
||||
organization: Organization! @goField(forceResolver: true)
|
||||
|
||||
versions(
|
||||
first: Int
|
||||
@@ -710,6 +729,7 @@ type Risk implements Node {
|
||||
note: String!
|
||||
|
||||
owner: People @goField(forceResolver: true)
|
||||
organization: Organization! @goField(forceResolver: true)
|
||||
|
||||
measures(
|
||||
first: Int
|
||||
@@ -1140,7 +1160,8 @@ input ImportMeasureInput {
|
||||
}
|
||||
|
||||
input CreateTaskInput {
|
||||
measureId: ID!
|
||||
organizationId: ID!
|
||||
measureId: ID
|
||||
name: String!
|
||||
description: String!
|
||||
timeEstimate: Duration
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -67,6 +67,7 @@ type Control struct {
|
||||
ReferenceID string `json:"referenceId"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Framework *Framework `json:"framework"`
|
||||
Measures *MeasureConnection `json:"measures"`
|
||||
Policies *PolicyConnection `json:"policies"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
@@ -215,11 +216,12 @@ type CreateRiskPolicyMappingPayload struct {
|
||||
}
|
||||
|
||||
type CreateTaskInput struct {
|
||||
MeasureID gid.GID `json:"measureId"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
TimeEstimate *time.Duration `json:"timeEstimate,omitempty"`
|
||||
AssignedToID *gid.GID `json:"assignedToId,omitempty"`
|
||||
OrganizationID gid.GID `json:"organizationId"`
|
||||
MeasureID *gid.GID `json:"measureId,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
TimeEstimate *time.Duration `json:"timeEstimate,omitempty"`
|
||||
AssignedToID *gid.GID `json:"assignedToId,omitempty"`
|
||||
}
|
||||
|
||||
type CreateTaskPayload struct {
|
||||
@@ -389,6 +391,8 @@ type Evidence struct {
|
||||
Filename string `json:"filename"`
|
||||
URL *string `json:"url,omitempty"`
|
||||
Description string `json:"description"`
|
||||
Task *Task `json:"task,omitempty"`
|
||||
Measure *Measure `json:"measure"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
@@ -407,12 +411,13 @@ type EvidenceEdge struct {
|
||||
}
|
||||
|
||||
type Framework struct {
|
||||
ID gid.GID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Controls *ControlConnection `json:"controls"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
ID gid.GID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Organization *Organization `json:"organization"`
|
||||
Controls *ControlConnection `json:"controls"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
func (Framework) IsNode() {}
|
||||
@@ -509,6 +514,7 @@ type Organization struct {
|
||||
Policies *PolicyConnection `json:"policies"`
|
||||
Measures *MeasureConnection `json:"measures"`
|
||||
Risks *RiskConnection `json:"risks"`
|
||||
Tasks *TaskConnection `json:"tasks"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
@@ -567,6 +573,7 @@ type Policy struct {
|
||||
Description string `json:"description"`
|
||||
CurrentPublishedVersion *int `json:"currentPublishedVersion,omitempty"`
|
||||
Owner *People `json:"owner"`
|
||||
Organization *Organization `json:"organization"`
|
||||
Versions *PolicyVersionConnection `json:"versions"`
|
||||
Controls *ControlConnection `json:"controls"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
@@ -702,6 +709,7 @@ type Risk struct {
|
||||
ResidualSeverity int `json:"residualSeverity"`
|
||||
Note string `json:"note"`
|
||||
Owner *People `json:"owner,omitempty"`
|
||||
Organization *Organization `json:"organization"`
|
||||
Measures *MeasureConnection `json:"measures"`
|
||||
Policies *PolicyConnection `json:"policies"`
|
||||
Controls *ControlConnection `json:"controls"`
|
||||
@@ -742,6 +750,8 @@ type Task struct {
|
||||
State coredata.TaskState `json:"state"`
|
||||
TimeEstimate *time.Duration `json:"timeEstimate,omitempty"`
|
||||
AssignedTo *People `json:"assignedTo,omitempty"`
|
||||
Organization *Organization `json:"organization"`
|
||||
Measure *Measure `json:"measure,omitempty"`
|
||||
Evidences *EvidenceConnection `json:"evidences"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
@@ -943,6 +953,7 @@ type Vendor struct {
|
||||
ID gid.GID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
Organization *Organization `json:"organization"`
|
||||
ComplianceReports *VendorComplianceReportConnection `json:"complianceReports"`
|
||||
RiskAssessments *VendorRiskAssessmentConnection `json:"riskAssessments"`
|
||||
BusinessOwner *People `json:"businessOwner,omitempty"`
|
||||
|
||||
@@ -20,6 +20,23 @@ import (
|
||||
"github.com/vektah/gqlparser/v2/gqlerror"
|
||||
)
|
||||
|
||||
// Framework is the resolver for the framework field.
|
||||
func (r *controlResolver) Framework(ctx context.Context, obj *types.Control) (*types.Framework, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
control, err := svc.Controls.Get(ctx, obj.ID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get control: %w", err))
|
||||
}
|
||||
|
||||
framework, err := svc.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) (*types.MeasureConnection, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
@@ -87,6 +104,61 @@ func (r *evidenceResolver) FileURL(ctx context.Context, obj *types.Evidence) (*s
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// Task is the resolver for the task field.
|
||||
func (r *evidenceResolver) Task(ctx context.Context, obj *types.Evidence) (*types.Task, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
evidence, err := svc.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 := svc.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) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
evidence, err := svc.Evidences.Get(ctx, obj.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot load evidence: %w", err)
|
||||
}
|
||||
|
||||
measure, err := svc.Measures.Get(ctx, evidence.MeasureID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot load measure: %w", err)
|
||||
}
|
||||
|
||||
return types.NewMeasure(measure), nil
|
||||
}
|
||||
|
||||
// Organization is the resolver for the organization field.
|
||||
func (r *frameworkResolver) Organization(ctx context.Context, obj *types.Framework) (*types.Organization, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
framework, err := svc.Frameworks.Get(ctx, obj.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot load framework: %w", err)
|
||||
}
|
||||
|
||||
organization, err := svc.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) (*types.ControlConnection, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
@@ -689,10 +761,11 @@ func (r *mutationResolver) CreateTask(ctx context.Context, input types.CreateTas
|
||||
svc := GetTenantService(ctx, r.proboSvc, input.MeasureID.TenantID())
|
||||
|
||||
task, err := svc.Tasks.Create(ctx, probo.CreateTaskRequest{
|
||||
MeasureID: input.MeasureID,
|
||||
Name: input.Name,
|
||||
Description: input.Description,
|
||||
TimeEstimate: input.TimeEstimate,
|
||||
MeasureID: input.MeasureID,
|
||||
OrganizationID: input.OrganizationID,
|
||||
Name: input.Name,
|
||||
Description: input.Description,
|
||||
TimeEstimate: input.TimeEstimate,
|
||||
})
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot create task: %w", err))
|
||||
@@ -1416,6 +1489,31 @@ func (r *organizationResolver) Risks(ctx context.Context, obj *types.Organizatio
|
||||
return types.NewRiskConnection(page), 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) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, 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 := svc.Tasks.ListForOrganizationID(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot list organization tasks: %w", err))
|
||||
}
|
||||
|
||||
return types.NewTaskConnection(page), nil
|
||||
}
|
||||
|
||||
// Owner is the resolver for the owner field.
|
||||
func (r *policyResolver) Owner(ctx context.Context, obj *types.Policy) (*types.People, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
@@ -1434,6 +1532,23 @@ func (r *policyResolver) Owner(ctx context.Context, obj *types.Policy) (*types.P
|
||||
return types.NewPeople(owner), nil
|
||||
}
|
||||
|
||||
// Organization is the resolver for the organization field.
|
||||
func (r *policyResolver) Organization(ctx context.Context, obj *types.Policy) (*types.Organization, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
policy, err := svc.Policies.Get(ctx, obj.ID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get policy: %w", err))
|
||||
}
|
||||
|
||||
organization, err := svc.Organizations.Get(ctx, policy.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 *policyResolver) Versions(ctx context.Context, obj *types.Policy, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.PolicyVersionOrderBy, filter *types.PolicyVersionFilter) (*types.PolicyVersionConnection, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
@@ -1727,6 +1842,23 @@ func (r *riskResolver) Owner(ctx context.Context, obj *types.Risk) (*types.Peopl
|
||||
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) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
risk, err := svc.Risks.Get(ctx, obj.ID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get risk: %w", err))
|
||||
}
|
||||
|
||||
organization, err := svc.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) (*types.MeasureConnection, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
@@ -1823,6 +1955,40 @@ func (r *taskResolver) AssignedTo(ctx context.Context, obj *types.Task) (*types.
|
||||
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) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
task, err := svc.Tasks.Get(ctx, obj.ID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get task: %w", err))
|
||||
}
|
||||
|
||||
organization, err := svc.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) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
task, err := svc.Tasks.Get(ctx, obj.ID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get task: %w", err))
|
||||
}
|
||||
|
||||
measure, err := svc.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) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
@@ -1859,6 +2025,23 @@ func (r *userResolver) People(ctx context.Context, obj *types.User, organization
|
||||
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) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
vendor, err := svc.Vendors.Get(ctx, obj.ID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get vendor: %w", err))
|
||||
}
|
||||
|
||||
organization, err := svc.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) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
Reference in New Issue
Block a user