diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f1d7f06a..98ca302cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,11 @@ All notable changes to this project will be documented in this file. - New bidirectional relationships: - Control objects now expose a `policies` field to list associated policies - Policy objects now expose a `controls` field to list associated controls +- Added vendor compliance reports: + - New GraphQL types `VendorComplianceReport` and related connection types + - New GraphQL mutations `uploadVendorComplianceReport` and `deleteVendorComplianceReport` + - New `complianceReports` field on the Vendor type + - Support for uploading, viewing, and managing vendor compliance documentation ### Changed diff --git a/pkg/coredata/entity_type_reg.go b/pkg/coredata/entity_type_reg.go index 12c01c134..b7c139ec3 100644 --- a/pkg/coredata/entity_type_reg.go +++ b/pkg/coredata/entity_type_reg.go @@ -20,11 +20,11 @@ const ( MitigationEntityType TaskEntityType EvidenceEntityType - _ControlStateTransitionEntityType - _TaskStateTransitionEntityType + _ControlStateTransitionEntityType // UNUSED + _TaskStateTransitionEntityType // UNUSED VendorEntityType PeopleEntityType - _EvidenceStateTransitionEntityType + VendorComplianceReportEntityType PolicyEntityType UserEntityType SessionEntityType diff --git a/pkg/coredata/migrations/20250409T081100Z.sql b/pkg/coredata/migrations/20250409T081100Z.sql new file mode 100644 index 000000000..a3883703e --- /dev/null +++ b/pkg/coredata/migrations/20250409T081100Z.sql @@ -0,0 +1,12 @@ +CREATE TABLE vendor_compliance_reports ( + id TEXT PRIMARY KEY, + tenant_id TEXT NOT NULL, + vendor_id TEXT NOT NULL REFERENCES vendors(id), + report_date DATE NOT NULL, + valid_until DATE, + report_name TEXT NOT NULL, + file_key TEXT NOT NULL, + file_size INTEGER NOT NULL, + created_at TIMESTAMP NOT NULL, + updated_at TIMESTAMP NOT NULL +); diff --git a/pkg/coredata/vendor_compliance_report.go b/pkg/coredata/vendor_compliance_report.go new file mode 100644 index 000000000..b8c4f3f80 --- /dev/null +++ b/pkg/coredata/vendor_compliance_report.go @@ -0,0 +1,215 @@ +// Copyright (c) 2025 Probo Inc . +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +package coredata + +import ( + "context" + "fmt" + "maps" + "time" + + "github.com/getprobo/probo/pkg/gid" + "github.com/getprobo/probo/pkg/page" + "github.com/jackc/pgx/v5" + "go.gearno.de/kit/pg" +) + +type ( + VendorComplianceReport struct { + ID gid.GID + VendorID gid.GID + ReportDate time.Time + ValidUntil *time.Time + ReportName string + FileKey string + FileSize int + CreatedAt time.Time + UpdatedAt time.Time + } + + VendorComplianceReports []*VendorComplianceReport +) + +func (c VendorComplianceReport) CursorKey(orderBy VendorComplianceReportOrderField) page.CursorKey { + switch orderBy { + case VendorComplianceReportOrderFieldReportDate: + return page.NewCursorKey(c.ID, c.ReportDate) + case VendorComplianceReportOrderFieldCreatedAt: + return page.NewCursorKey(c.ID, c.CreatedAt) + } + + panic(fmt.Sprintf("unsupported order by: %s", orderBy)) +} + +func (vcs *VendorComplianceReports) LoadForVendorID( + ctx context.Context, + conn pg.Conn, + scope Scoper, + vendorID gid.GID, + cursor *page.Cursor[VendorComplianceReportOrderField], +) error { + q := ` +SELECT + id, + report_date, + valid_until, + report_name, + file_key, + file_size, + created_at, + updated_at +FROM + vendor_compliance_reports +WHERE + %s + AND vendor_id = @vendor_id + AND %s +` + + q = fmt.Sprintf(q, scope.SQLFragment(), cursor.SQLFragment()) + + args := pgx.NamedArgs{"vendor_id": vendorID} + maps.Copy(args, scope.SQLArguments()) + maps.Copy(args, cursor.SQLArguments()) + + rows, err := conn.Query(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot query vendor compliance reports: %w", err) + } + + vendorComplianceReports, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[VendorComplianceReport]) + if err != nil { + return fmt.Errorf("cannot collect vendor compliance reports: %w", err) + } + + *vcs = vendorComplianceReports + + return nil +} + +func (vcr *VendorComplianceReport) LoadByID( + ctx context.Context, + conn pg.Conn, + scope Scoper, + vendorComplianceReportID gid.GID, +) error { + q := ` +SELECT + id, + vendor_id, + report_date, + valid_until, + report_name, + file_key, + file_size, + created_at, + updated_at +FROM + vendor_compliance_reports +WHERE + %s + AND id = @id +LIMIT 1; +` + + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.NamedArgs{"id": vendorComplianceReportID} + maps.Copy(args, scope.SQLArguments()) + + rows, err := conn.Query(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot query vendor compliance report: %w", err) + } + + vendorComplianceReport, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[VendorComplianceReport]) + if err != nil { + return fmt.Errorf("cannot collect vendor compliance report: %w", err) + } + + *vcr = vendorComplianceReport + + return nil +} + +func (vcr *VendorComplianceReport) Insert( + ctx context.Context, + conn pg.Conn, + scope Scoper, +) error { + q := ` +INSERT INTO + vendor_compliance_reports ( + id, + tenant_id, + vendor_id, + report_date, + valid_until, + report_name, + file_key, + file_size, + created_at, + updated_at + ) +VALUES ( + @id, + @tenant_id, + @vendor_id, + @report_date, + @valid_until, + @report_name, + @file_key, + @file_size, + @created_at, + @updated_at +) +` + args := pgx.NamedArgs{ + "id": vcr.ID, + "tenant_id": scope.GetTenantID(), + "vendor_id": vcr.VendorID, + "report_date": vcr.ReportDate, + "valid_until": vcr.ValidUntil, + "report_name": vcr.ReportName, + "file_key": vcr.FileKey, + "file_size": vcr.FileSize, + "created_at": vcr.CreatedAt, + "updated_at": vcr.UpdatedAt, + } + + _, err := conn.Exec(ctx, q, args) + return err +} + +func (vcr *VendorComplianceReport) Delete( + ctx context.Context, + conn pg.Conn, + scope Scoper, +) error { + q := ` +DELETE FROM + vendor_compliance_reports +WHERE + %s + AND id = @id +` + + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.NamedArgs{"id": vcr.ID} + + _, err := conn.Exec(ctx, q, args) + return err +} diff --git a/pkg/coredata/vendor_compliance_report_order_field.go b/pkg/coredata/vendor_compliance_report_order_field.go new file mode 100644 index 000000000..54c127340 --- /dev/null +++ b/pkg/coredata/vendor_compliance_report_order_field.go @@ -0,0 +1,41 @@ +// Copyright (c) 2025 Probo Inc . +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +package coredata + +type ( + VendorComplianceReportOrderField string +) + +const ( + VendorComplianceReportOrderFieldReportDate VendorComplianceReportOrderField = "REPORT_DATE" + VendorComplianceReportOrderFieldCreatedAt VendorComplianceReportOrderField = "CREATED_AT" +) + +func (p VendorComplianceReportOrderField) Column() string { + return string(p) +} + +func (p VendorComplianceReportOrderField) String() string { + return string(p) +} + +func (p VendorComplianceReportOrderField) MarshalText() ([]byte, error) { + return []byte(p.String()), nil +} + +func (p *VendorComplianceReportOrderField) UnmarshalText(text []byte) error { + *p = VendorComplianceReportOrderField(text) + return nil +} diff --git a/pkg/probo/service.go b/pkg/probo/service.go index 9cc16443e..4cdd7c760 100644 --- a/pkg/probo/service.go +++ b/pkg/probo/service.go @@ -38,16 +38,17 @@ type ( scope coredata.Scoper - Frameworks *FrameworkService - Mitigations *MitigationService - Tasks *TaskService - Evidences *EvidenceService - Organizations *OrganizationService - Vendors *VendorService - Peoples *PeopleService - Policies *PolicyService - Controls *ControlService - Risks *RiskService + Frameworks *FrameworkService + Mitigations *MitigationService + Tasks *TaskService + Evidences *EvidenceService + Organizations *OrganizationService + Vendors *VendorService + Peoples *PeopleService + Policies *PolicyService + Controls *ControlService + Risks *RiskService + VendorComplianceReports *VendorComplianceReportService } ) @@ -88,6 +89,6 @@ func (s *Service) WithTenant(tenantID gid.TenantID) *TenantService { tenantService.Organizations = &OrganizationService{svc: tenantService} tenantService.Controls = &ControlService{svc: tenantService} tenantService.Risks = &RiskService{svc: tenantService} - + tenantService.VendorComplianceReports = &VendorComplianceReportService{svc: tenantService} return tenantService } diff --git a/pkg/probo/vendor_compliance_report_service.go b/pkg/probo/vendor_compliance_report_service.go new file mode 100644 index 000000000..14b0a5d48 --- /dev/null +++ b/pkg/probo/vendor_compliance_report_service.go @@ -0,0 +1,195 @@ +// Copyright (c) 2025 Probo Inc . +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +package probo + +import ( + "context" + "fmt" + "io" + "mime" + "net/url" + "path/filepath" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/getprobo/probo/pkg/coredata" + "github.com/getprobo/probo/pkg/gid" + "github.com/getprobo/probo/pkg/page" + "go.gearno.de/crypto/uuid" + "go.gearno.de/kit/pg" +) + +type ( + VendorComplianceReportService struct { + svc *TenantService + } + + VendorComplianceReportCreateRequest struct { + File io.Reader + ReportDate time.Time + ValidUntil *time.Time + ReportName string + } +) + +func (s VendorComplianceReportService) ListForVendorID( + ctx context.Context, + vendorID gid.GID, + cursor *page.Cursor[coredata.VendorComplianceReportOrderField], +) (*page.Page[*coredata.VendorComplianceReport, coredata.VendorComplianceReportOrderField], error) { + var vendorComplianceReports coredata.VendorComplianceReports + + err := s.svc.pg.WithConn( + ctx, + func(conn pg.Conn) error { + return vendorComplianceReports.LoadForVendorID(ctx, conn, s.svc.scope, vendorID, cursor) + }, + ) + + if err != nil { + return nil, err + } + + return page.NewPage(vendorComplianceReports, cursor), nil +} + +func (s VendorComplianceReportService) Upload( + ctx context.Context, + vendorID gid.GID, + req *VendorComplianceReportCreateRequest, +) (*coredata.VendorComplianceReport, error) { + objectKey, err := uuid.NewV7() + if err != nil { + return nil, fmt.Errorf("cannot generate object key: %w", err) + } + + mimeType := mime.TypeByExtension(filepath.Ext(req.ReportName)) + + _, err = s.svc.s3.PutObject(ctx, &s3.PutObjectInput{ + Bucket: &s.svc.bucket, + Key: aws.String(objectKey.String()), + Body: req.File, + ContentType: &mimeType, + }) + if err != nil { + return nil, fmt.Errorf("cannot upload file to S3: %w", err) + } + + headOutput, err := s.svc.s3.HeadObject(ctx, &s3.HeadObjectInput{ + Bucket: aws.String(s.svc.bucket), + Key: aws.String(objectKey.String()), + }) + if err != nil { + return nil, fmt.Errorf("cannot get object metadata: %w", err) + } + + now := time.Now() + + vendorComplianceReportID, err := gid.NewGID(s.svc.scope.GetTenantID(), coredata.VendorComplianceReportEntityType) + if err != nil { + return nil, fmt.Errorf("cannot generate vendor compliance report ID: %w", err) + } + + vendorComplianceReport := &coredata.VendorComplianceReport{ + ID: vendorComplianceReportID, + VendorID: vendorID, + ReportDate: req.ReportDate, + ValidUntil: req.ValidUntil, + ReportName: req.ReportName, + FileKey: objectKey.String(), + FileSize: int(*headOutput.ContentLength), + CreatedAt: now, + UpdatedAt: now, + } + + err = s.svc.pg.WithConn( + ctx, + func(conn pg.Conn) error { + return vendorComplianceReport.Insert(ctx, conn, s.svc.scope) + }, + ) + + if err != nil { + return nil, err + } + + return vendorComplianceReport, nil +} + +func (s VendorComplianceReportService) Get( + ctx context.Context, + vendorComplianceReportID gid.GID, +) (*coredata.VendorComplianceReport, error) { + vendorComplianceReport := &coredata.VendorComplianceReport{} + + err := s.svc.pg.WithConn( + ctx, + func(conn pg.Conn) error { + return vendorComplianceReport.LoadByID(ctx, conn, s.svc.scope, vendorComplianceReportID) + }, + ) + + if err != nil { + return nil, fmt.Errorf("cannot load vendor compliance report: %w", err) + } + + return vendorComplianceReport, nil +} + +func (s VendorComplianceReportService) GenerateFileURL( + ctx context.Context, + vendorComplianceReportID gid.GID, + expiresIn time.Duration, +) (string, error) { + vendorComplianceReport, err := s.Get(ctx, vendorComplianceReportID) + if err != nil { + return "", fmt.Errorf("cannot get vendor compliance report: %w", err) + } + + presignClient := s3.NewPresignClient(s.svc.s3) + + // Use RFC 6266/5987 encoding for filename with UTF-8 support + encodedFilename := url.QueryEscape(vendorComplianceReport.ReportName) + contentDisposition := fmt.Sprintf("attachment; filename=\"%s\"; filename*=UTF-8''%s", + encodedFilename, encodedFilename) + + presignedReq, err := presignClient.PresignGetObject(ctx, &s3.GetObjectInput{ + Bucket: aws.String(s.svc.bucket), + Key: aws.String(vendorComplianceReport.FileKey), + ResponseContentDisposition: aws.String(contentDisposition), + }, func(opts *s3.PresignOptions) { + opts.Expires = expiresIn + }) + if err != nil { + return "", fmt.Errorf("cannot presign GetObject request: %w", err) + } + + return presignedReq.URL, nil +} + +func (s VendorComplianceReportService) Delete( + ctx context.Context, + vendorComplianceReportID gid.GID, +) error { + vendorComplianceReport := &coredata.VendorComplianceReport{ID: vendorComplianceReportID} + + return s.svc.pg.WithConn( + ctx, + func(conn pg.Conn) error { + return vendorComplianceReport.Delete(ctx, conn, s.svc.scope) + }, + ) +} diff --git a/pkg/server/api/console/v1/schema.graphql b/pkg/server/api/console/v1/schema.graphql index 18fe2fd67..867095f5b 100644 --- a/pkg/server/api/console/v1/schema.graphql +++ b/pkg/server/api/console/v1/schema.graphql @@ -226,6 +226,20 @@ enum EvidenceOrderField CREATED_AT } +enum VendorComplianceReportOrderField + @goModel( + model: "github.com/getprobo/probo/pkg/coredata.VendorComplianceReportOrderField" + ) { + REPORT_DATE + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.VendorComplianceReportOrderFieldReportDate" + ) + CREATED_AT + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.VendorComplianceReportOrderFieldCreatedAt" + ) +} + enum OrganizationOrderField { NAME CREATED_AT @@ -313,6 +327,14 @@ input EvidenceOrder field: EvidenceOrderField! } +input VendorComplianceReportOrder + @goModel( + model: "github.com/getprobo/probo/pkg/server/api/console/v1/types.VendorComplianceReportOrderBy" + ) { + direction: OrderDirection! + field: VendorComplianceReportOrderField! +} + input OrganizationOrder { direction: OrderDirection! field: OrganizationOrderField! @@ -406,6 +428,15 @@ type Vendor implements Node { id: ID! name: String! description: String! + + complianceReports( + first: Int + after: CursorKey + last: Int + before: CursorKey + orderBy: VendorComplianceReportOrder + ): VendorComplianceReportConnection! @goField(forceResolver: true) + serviceStartAt: Datetime! serviceTerminationAt: Datetime serviceCriticality: ServiceCriticality! @@ -417,6 +448,20 @@ type Vendor implements Node { updatedAt: Datetime! } +type VendorComplianceReport implements Node { + id: ID! + vendor: Vendor! @goField(forceResolver: true) + reportDate: Datetime! + validUntil: Datetime + reportName: String! + + fileUrl: String! @goField(forceResolver: true) + fileSize: Int! + + createdAt: Datetime! + updatedAt: Datetime! +} + type Framework implements Node { id: ID! name: String! @@ -699,6 +744,16 @@ type RiskEdge { node: Risk! } +type VendorComplianceReportConnection { + edges: [VendorComplianceReportEdge!]! + pageInfo: PageInfo! +} + +type VendorComplianceReportEdge { + cursor: CursorKey! + node: VendorComplianceReport! +} + # Root Types type Query { node(id: ID!): Node! @@ -777,6 +832,14 @@ type Mutation { createEvidence(input: CreateEvidenceInput!): CreateEvidencePayload! deleteEvidence(input: DeleteEvidenceInput!): DeleteEvidencePayload! + # Vendor Compliance Report mutations + uploadVendorComplianceReport( + input: UploadVendorComplianceReportInput! + ): UploadVendorComplianceReportPayload! + deleteVendorComplianceReport( + input: DeleteVendorComplianceReportInput! + ): DeleteVendorComplianceReportPayload! + # Policy mutations createPolicy(input: CreatePolicyInput!): CreatePolicyPayload! updatePolicy(input: UpdatePolicyInput!): UpdatePolicyPayload! @@ -999,6 +1062,18 @@ input DeleteEvidenceInput { evidenceId: ID! } +input UploadVendorComplianceReportInput { + vendorId: ID! + reportDate: Datetime! + validUntil: Datetime + reportName: String! + file: Upload! +} + +input DeleteVendorComplianceReportInput { + reportId: ID! +} + input CreatePolicyInput { organizationId: ID! name: String! @@ -1173,6 +1248,14 @@ type DeleteEvidencePayload { deletedEvidenceId: ID! } +type UploadVendorComplianceReportPayload { + vendorComplianceReportEdge: VendorComplianceReportEdge! +} + +type DeleteVendorComplianceReportPayload { + deletedVendorComplianceReportId: ID! +} + type CreatePolicyPayload { policyEdge: PolicyEdge! } diff --git a/pkg/server/api/console/v1/schema/schema.go b/pkg/server/api/console/v1/schema/schema.go index ef85115df..e9091230d 100644 --- a/pkg/server/api/console/v1/schema/schema.go +++ b/pkg/server/api/console/v1/schema/schema.go @@ -52,6 +52,8 @@ type ResolverRoot interface { Query() QueryResolver Risk() RiskResolver Task() TaskResolver + Vendor() VendorResolver + VendorComplianceReport() VendorComplianceReportResolver Viewer() ViewerResolver } @@ -176,6 +178,10 @@ type ComplexityRoot struct { DeletedTaskID func(childComplexity int) int } + DeleteVendorComplianceReportPayload struct { + DeletedVendorComplianceReportID func(childComplexity int) int + } + DeleteVendorPayload struct { DeletedVendorID func(childComplexity int) int } @@ -289,6 +295,7 @@ type ComplexityRoot struct { DeleteRiskMapping func(childComplexity int, input types.DeleteRiskMappingInput) int DeleteTask func(childComplexity int, input types.DeleteTaskInput) int DeleteVendor func(childComplexity int, input types.DeleteVendorInput) int + DeleteVendorComplianceReport func(childComplexity int, input types.DeleteVendorComplianceReportInput) int FulfillEvidence func(childComplexity int, input types.FulfillEvidenceInput) int ImportFramework func(childComplexity int, input types.ImportFrameworkInput) int ImportMitigation func(childComplexity int, input types.ImportMitigationInput) int @@ -304,6 +311,7 @@ type ComplexityRoot struct { UpdateRisk func(childComplexity int, input types.UpdateRiskInput) int UpdateTask func(childComplexity int, input types.UpdateTaskInput) int UpdateVendor func(childComplexity int, input types.UpdateVendorInput) int + UploadVendorComplianceReport func(childComplexity int, input types.UploadVendorComplianceReportInput) int } Organization struct { @@ -477,6 +485,10 @@ type ComplexityRoot struct { Vendor func(childComplexity int) int } + UploadVendorComplianceReportPayload struct { + VendorComplianceReportEdge func(childComplexity int) int + } + User struct { CreatedAt func(childComplexity int) int Email func(childComplexity int) int @@ -496,6 +508,7 @@ type ComplexityRoot struct { } Vendor struct { + ComplianceReports func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorComplianceReportOrderBy) int CreatedAt func(childComplexity int) int Description func(childComplexity int) int ID func(childComplexity int) int @@ -510,6 +523,28 @@ type ComplexityRoot struct { UpdatedAt func(childComplexity int) int } + VendorComplianceReport struct { + CreatedAt func(childComplexity int) int + FileSize func(childComplexity int) int + FileURL func(childComplexity int) int + ID func(childComplexity int) int + ReportDate func(childComplexity int) int + ReportName func(childComplexity int) int + UpdatedAt func(childComplexity int) int + ValidUntil func(childComplexity int) int + Vendor func(childComplexity int) int + } + + VendorComplianceReportConnection struct { + Edges func(childComplexity int) int + PageInfo func(childComplexity int) int + } + + VendorComplianceReportEdge struct { + Cursor func(childComplexity int) int + Node func(childComplexity int) int + } + VendorConnection struct { Edges func(childComplexity int) int PageInfo func(childComplexity int) int @@ -580,6 +615,8 @@ type MutationResolver interface { FulfillEvidence(ctx context.Context, input types.FulfillEvidenceInput) (*types.FulfillEvidencePayload, error) CreateEvidence(ctx context.Context, input types.CreateEvidenceInput) (*types.CreateEvidencePayload, error) DeleteEvidence(ctx context.Context, input types.DeleteEvidenceInput) (*types.DeleteEvidencePayload, error) + UploadVendorComplianceReport(ctx context.Context, input types.UploadVendorComplianceReportInput) (*types.UploadVendorComplianceReportPayload, error) + DeleteVendorComplianceReport(ctx context.Context, input types.DeleteVendorComplianceReportInput) (*types.DeleteVendorComplianceReportPayload, error) CreatePolicy(ctx context.Context, input types.CreatePolicyInput) (*types.CreatePolicyPayload, error) UpdatePolicy(ctx context.Context, input types.UpdatePolicyInput) (*types.UpdatePolicyPayload, error) DeletePolicy(ctx context.Context, input types.DeletePolicyInput) (*types.DeletePolicyPayload, error) @@ -609,6 +646,14 @@ type TaskResolver interface { AssignedTo(ctx context.Context, obj *types.Task) (*types.People, error) Evidences(ctx context.Context, obj *types.Task, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.EvidenceOrderBy) (*types.EvidenceConnection, error) } +type VendorResolver interface { + ComplianceReports(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorComplianceReportOrderBy) (*types.VendorComplianceReportConnection, error) +} +type VendorComplianceReportResolver interface { + Vendor(ctx context.Context, obj *types.VendorComplianceReport) (*types.Vendor, error) + + FileURL(ctx context.Context, obj *types.VendorComplianceReport) (string, error) +} type ViewerResolver interface { Organizations(ctx context.Context, obj *types.Viewer, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrganizationOrder) (*types.OrganizationConnection, error) } @@ -894,6 +939,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.DeleteTaskPayload.DeletedTaskID(childComplexity), true + case "DeleteVendorComplianceReportPayload.deletedVendorComplianceReportId": + if e.complexity.DeleteVendorComplianceReportPayload.DeletedVendorComplianceReportID == nil { + break + } + + return e.complexity.DeleteVendorComplianceReportPayload.DeletedVendorComplianceReportID(childComplexity), true + case "DeleteVendorPayload.deletedVendorId": if e.complexity.DeleteVendorPayload.DeletedVendorID == nil { break @@ -1529,6 +1581,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.DeleteVendor(childComplexity, args["input"].(types.DeleteVendorInput)), true + case "Mutation.deleteVendorComplianceReport": + if e.complexity.Mutation.DeleteVendorComplianceReport == nil { + break + } + + args, err := ec.field_Mutation_deleteVendorComplianceReport_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.DeleteVendorComplianceReport(childComplexity, args["input"].(types.DeleteVendorComplianceReportInput)), true + case "Mutation.fulfillEvidence": if e.complexity.Mutation.FulfillEvidence == nil { break @@ -1709,6 +1773,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.UpdateVendor(childComplexity, args["input"].(types.UpdateVendorInput)), true + case "Mutation.uploadVendorComplianceReport": + if e.complexity.Mutation.UploadVendorComplianceReport == nil { + break + } + + args, err := ec.field_Mutation_uploadVendorComplianceReport_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.UploadVendorComplianceReport(childComplexity, args["input"].(types.UploadVendorComplianceReportInput)), true + case "Organization.createdAt": if e.complexity.Organization.CreatedAt == nil { break @@ -2352,6 +2428,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.UpdateVendorPayload.Vendor(childComplexity), true + case "UploadVendorComplianceReportPayload.vendorComplianceReportEdge": + if e.complexity.UploadVendorComplianceReportPayload.VendorComplianceReportEdge == nil { + break + } + + return e.complexity.UploadVendorComplianceReportPayload.VendorComplianceReportEdge(childComplexity), true + case "User.createdAt": if e.complexity.User.CreatedAt == nil { break @@ -2415,6 +2498,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.UserEdge.Node(childComplexity), true + case "Vendor.complianceReports": + if e.complexity.Vendor.ComplianceReports == nil { + break + } + + args, err := ec.field_Vendor_complianceReports_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Vendor.ComplianceReports(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey), args["orderBy"].(*types.VendorComplianceReportOrderBy)), true + case "Vendor.createdAt": if e.complexity.Vendor.CreatedAt == nil { break @@ -2499,6 +2594,97 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Vendor.UpdatedAt(childComplexity), true + case "VendorComplianceReport.createdAt": + if e.complexity.VendorComplianceReport.CreatedAt == nil { + break + } + + return e.complexity.VendorComplianceReport.CreatedAt(childComplexity), true + + case "VendorComplianceReport.fileSize": + if e.complexity.VendorComplianceReport.FileSize == nil { + break + } + + return e.complexity.VendorComplianceReport.FileSize(childComplexity), true + + case "VendorComplianceReport.fileUrl": + if e.complexity.VendorComplianceReport.FileURL == nil { + break + } + + return e.complexity.VendorComplianceReport.FileURL(childComplexity), true + + case "VendorComplianceReport.id": + if e.complexity.VendorComplianceReport.ID == nil { + break + } + + return e.complexity.VendorComplianceReport.ID(childComplexity), true + + case "VendorComplianceReport.reportDate": + if e.complexity.VendorComplianceReport.ReportDate == nil { + break + } + + return e.complexity.VendorComplianceReport.ReportDate(childComplexity), true + + case "VendorComplianceReport.reportName": + if e.complexity.VendorComplianceReport.ReportName == nil { + break + } + + return e.complexity.VendorComplianceReport.ReportName(childComplexity), true + + case "VendorComplianceReport.updatedAt": + if e.complexity.VendorComplianceReport.UpdatedAt == nil { + break + } + + return e.complexity.VendorComplianceReport.UpdatedAt(childComplexity), true + + case "VendorComplianceReport.validUntil": + if e.complexity.VendorComplianceReport.ValidUntil == nil { + break + } + + return e.complexity.VendorComplianceReport.ValidUntil(childComplexity), true + + case "VendorComplianceReport.vendor": + if e.complexity.VendorComplianceReport.Vendor == nil { + break + } + + return e.complexity.VendorComplianceReport.Vendor(childComplexity), true + + case "VendorComplianceReportConnection.edges": + if e.complexity.VendorComplianceReportConnection.Edges == nil { + break + } + + return e.complexity.VendorComplianceReportConnection.Edges(childComplexity), true + + case "VendorComplianceReportConnection.pageInfo": + if e.complexity.VendorComplianceReportConnection.PageInfo == nil { + break + } + + return e.complexity.VendorComplianceReportConnection.PageInfo(childComplexity), true + + case "VendorComplianceReportEdge.cursor": + if e.complexity.VendorComplianceReportEdge.Cursor == nil { + break + } + + return e.complexity.VendorComplianceReportEdge.Cursor(childComplexity), true + + case "VendorComplianceReportEdge.node": + if e.complexity.VendorComplianceReportEdge.Node == nil { + break + } + + return e.complexity.VendorComplianceReportEdge.Node(childComplexity), true + case "VendorConnection.edges": if e.complexity.VendorConnection.Edges == nil { break @@ -2586,6 +2772,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputDeleteRiskInput, ec.unmarshalInputDeleteRiskMappingInput, ec.unmarshalInputDeleteTaskInput, + ec.unmarshalInputDeleteVendorComplianceReportInput, ec.unmarshalInputDeleteVendorInput, ec.unmarshalInputEvidenceOrder, ec.unmarshalInputFrameworkOrder, @@ -2610,7 +2797,9 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputUpdateRiskInput, ec.unmarshalInputUpdateTaskInput, ec.unmarshalInputUpdateVendorInput, + ec.unmarshalInputUploadVendorComplianceReportInput, ec.unmarshalInputUserOrder, + ec.unmarshalInputVendorComplianceReportOrder, ec.unmarshalInputVendorOrder, ) first := true @@ -2937,6 +3126,20 @@ enum EvidenceOrderField CREATED_AT } +enum VendorComplianceReportOrderField + @goModel( + model: "github.com/getprobo/probo/pkg/coredata.VendorComplianceReportOrderField" + ) { + REPORT_DATE + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.VendorComplianceReportOrderFieldReportDate" + ) + CREATED_AT + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.VendorComplianceReportOrderFieldCreatedAt" + ) +} + enum OrganizationOrderField { NAME CREATED_AT @@ -3024,6 +3227,14 @@ input EvidenceOrder field: EvidenceOrderField! } +input VendorComplianceReportOrder + @goModel( + model: "github.com/getprobo/probo/pkg/server/api/console/v1/types.VendorComplianceReportOrderBy" + ) { + direction: OrderDirection! + field: VendorComplianceReportOrderField! +} + input OrganizationOrder { direction: OrderDirection! field: OrganizationOrderField! @@ -3117,6 +3328,15 @@ type Vendor implements Node { id: ID! name: String! description: String! + + complianceReports( + first: Int + after: CursorKey + last: Int + before: CursorKey + orderBy: VendorComplianceReportOrder + ): VendorComplianceReportConnection! @goField(forceResolver: true) + serviceStartAt: Datetime! serviceTerminationAt: Datetime serviceCriticality: ServiceCriticality! @@ -3128,6 +3348,20 @@ type Vendor implements Node { updatedAt: Datetime! } +type VendorComplianceReport implements Node { + id: ID! + vendor: Vendor! @goField(forceResolver: true) + reportDate: Datetime! + validUntil: Datetime + reportName: String! + + fileUrl: String! @goField(forceResolver: true) + fileSize: Int! + + createdAt: Datetime! + updatedAt: Datetime! +} + type Framework implements Node { id: ID! name: String! @@ -3410,6 +3644,16 @@ type RiskEdge { node: Risk! } +type VendorComplianceReportConnection { + edges: [VendorComplianceReportEdge!]! + pageInfo: PageInfo! +} + +type VendorComplianceReportEdge { + cursor: CursorKey! + node: VendorComplianceReport! +} + # Root Types type Query { node(id: ID!): Node! @@ -3488,6 +3732,14 @@ type Mutation { createEvidence(input: CreateEvidenceInput!): CreateEvidencePayload! deleteEvidence(input: DeleteEvidenceInput!): DeleteEvidencePayload! + # Vendor Compliance Report mutations + uploadVendorComplianceReport( + input: UploadVendorComplianceReportInput! + ): UploadVendorComplianceReportPayload! + deleteVendorComplianceReport( + input: DeleteVendorComplianceReportInput! + ): DeleteVendorComplianceReportPayload! + # Policy mutations createPolicy(input: CreatePolicyInput!): CreatePolicyPayload! updatePolicy(input: UpdatePolicyInput!): UpdatePolicyPayload! @@ -3710,6 +3962,18 @@ input DeleteEvidenceInput { evidenceId: ID! } +input UploadVendorComplianceReportInput { + vendorId: ID! + reportDate: Datetime! + validUntil: Datetime + reportName: String! + file: Upload! +} + +input DeleteVendorComplianceReportInput { + reportId: ID! +} + input CreatePolicyInput { organizationId: ID! name: String! @@ -3884,6 +4148,14 @@ type DeleteEvidencePayload { deletedEvidenceId: ID! } +type UploadVendorComplianceReportPayload { + vendorComplianceReportEdge: VendorComplianceReportEdge! +} + +type DeleteVendorComplianceReportPayload { + deletedVendorComplianceReportId: ID! +} + type CreatePolicyPayload { policyEdge: PolicyEdge! } @@ -5037,6 +5309,29 @@ func (ec *executionContext) field_Mutation_deleteTask_argsInput( return zeroVal, nil } +func (ec *executionContext) field_Mutation_deleteVendorComplianceReport_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Mutation_deleteVendorComplianceReport_argsInput(ctx, rawArgs) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} +func (ec *executionContext) field_Mutation_deleteVendorComplianceReport_argsInput( + ctx context.Context, + rawArgs map[string]any, +) (types.DeleteVendorComplianceReportInput, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + if tmp, ok := rawArgs["input"]; ok { + return ec.unmarshalNDeleteVendorComplianceReportInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteVendorComplianceReportInput(ctx, tmp) + } + + var zeroVal types.DeleteVendorComplianceReportInput + return zeroVal, nil +} + func (ec *executionContext) field_Mutation_deleteVendor_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -5405,6 +5700,29 @@ func (ec *executionContext) field_Mutation_updateVendor_argsInput( return zeroVal, nil } +func (ec *executionContext) field_Mutation_uploadVendorComplianceReport_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Mutation_uploadVendorComplianceReport_argsInput(ctx, rawArgs) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} +func (ec *executionContext) field_Mutation_uploadVendorComplianceReport_argsInput( + ctx context.Context, + rawArgs map[string]any, +) (types.UploadVendorComplianceReportInput, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + if tmp, ok := rawArgs["input"]; ok { + return ec.unmarshalNUploadVendorComplianceReportInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUploadVendorComplianceReportInput(ctx, tmp) + } + + var zeroVal types.UploadVendorComplianceReportInput + return zeroVal, nil +} + func (ec *executionContext) field_Organization_frameworks_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -6401,6 +6719,101 @@ func (ec *executionContext) field_Task_evidences_argsOrderBy( return zeroVal, nil } +func (ec *executionContext) field_Vendor_complianceReports_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Vendor_complianceReports_argsFirst(ctx, rawArgs) + if err != nil { + return nil, err + } + args["first"] = arg0 + arg1, err := ec.field_Vendor_complianceReports_argsAfter(ctx, rawArgs) + if err != nil { + return nil, err + } + args["after"] = arg1 + arg2, err := ec.field_Vendor_complianceReports_argsLast(ctx, rawArgs) + if err != nil { + return nil, err + } + args["last"] = arg2 + arg3, err := ec.field_Vendor_complianceReports_argsBefore(ctx, rawArgs) + if err != nil { + return nil, err + } + args["before"] = arg3 + arg4, err := ec.field_Vendor_complianceReports_argsOrderBy(ctx, rawArgs) + if err != nil { + return nil, err + } + args["orderBy"] = arg4 + return args, nil +} +func (ec *executionContext) field_Vendor_complianceReports_argsFirst( + ctx context.Context, + rawArgs map[string]any, +) (*int, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("first")) + if tmp, ok := rawArgs["first"]; ok { + return ec.unmarshalOInt2ᚖint(ctx, tmp) + } + + var zeroVal *int + return zeroVal, nil +} + +func (ec *executionContext) field_Vendor_complianceReports_argsAfter( + ctx context.Context, + rawArgs map[string]any, +) (*page.CursorKey, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("after")) + if tmp, ok := rawArgs["after"]; ok { + return ec.unmarshalOCursorKey2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋpageᚐCursorKey(ctx, tmp) + } + + var zeroVal *page.CursorKey + return zeroVal, nil +} + +func (ec *executionContext) field_Vendor_complianceReports_argsLast( + ctx context.Context, + rawArgs map[string]any, +) (*int, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("last")) + if tmp, ok := rawArgs["last"]; ok { + return ec.unmarshalOInt2ᚖint(ctx, tmp) + } + + var zeroVal *int + return zeroVal, nil +} + +func (ec *executionContext) field_Vendor_complianceReports_argsBefore( + ctx context.Context, + rawArgs map[string]any, +) (*page.CursorKey, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("before")) + if tmp, ok := rawArgs["before"]; ok { + return ec.unmarshalOCursorKey2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋpageᚐCursorKey(ctx, tmp) + } + + var zeroVal *page.CursorKey + return zeroVal, nil +} + +func (ec *executionContext) field_Vendor_complianceReports_argsOrderBy( + ctx context.Context, + rawArgs map[string]any, +) (*types.VendorComplianceReportOrderBy, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("orderBy")) + if tmp, ok := rawArgs["orderBy"]; ok { + return ec.unmarshalOVendorComplianceReportOrder2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorComplianceReportOrderBy(ctx, tmp) + } + + var zeroVal *types.VendorComplianceReportOrderBy + return zeroVal, nil +} + func (ec *executionContext) field_Viewer_organizations_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -8322,6 +8735,50 @@ func (ec *executionContext) fieldContext_DeleteTaskPayload_deletedTaskId(_ conte return fc, nil } +func (ec *executionContext) _DeleteVendorComplianceReportPayload_deletedVendorComplianceReportId(ctx context.Context, field graphql.CollectedField, obj *types.DeleteVendorComplianceReportPayload) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_DeleteVendorComplianceReportPayload_deletedVendorComplianceReportId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeletedVendorComplianceReportID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(gid.GID) + fc.Result = res + return ec.marshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_DeleteVendorComplianceReportPayload_deletedVendorComplianceReportId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "DeleteVendorComplianceReportPayload", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + func (ec *executionContext) _DeleteVendorPayload_deletedVendorId(ctx context.Context, field graphql.CollectedField, obj *types.DeleteVendorPayload) (ret graphql.Marshaler) { fc, err := ec.fieldContext_DeleteVendorPayload_deletedVendorId(ctx, field) if err != nil { @@ -12675,6 +13132,124 @@ func (ec *executionContext) fieldContext_Mutation_deleteEvidence(ctx context.Con return fc, nil } +func (ec *executionContext) _Mutation_uploadVendorComplianceReport(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_uploadVendorComplianceReport(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().UploadVendorComplianceReport(rctx, fc.Args["input"].(types.UploadVendorComplianceReportInput)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.UploadVendorComplianceReportPayload) + fc.Result = res + return ec.marshalNUploadVendorComplianceReportPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUploadVendorComplianceReportPayload(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_uploadVendorComplianceReport(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Mutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "vendorComplianceReportEdge": + return ec.fieldContext_UploadVendorComplianceReportPayload_vendorComplianceReportEdge(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type UploadVendorComplianceReportPayload", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Mutation_uploadVendorComplianceReport_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Mutation_deleteVendorComplianceReport(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_deleteVendorComplianceReport(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().DeleteVendorComplianceReport(rctx, fc.Args["input"].(types.DeleteVendorComplianceReportInput)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.DeleteVendorComplianceReportPayload) + fc.Result = res + return ec.marshalNDeleteVendorComplianceReportPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteVendorComplianceReportPayload(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_deleteVendorComplianceReport(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Mutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "deletedVendorComplianceReportId": + return ec.fieldContext_DeleteVendorComplianceReportPayload_deletedVendorComplianceReportId(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type DeleteVendorComplianceReportPayload", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Mutation_deleteVendorComplianceReport_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _Mutation_createPolicy(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Mutation_createPolicy(ctx, field) if err != nil { @@ -17227,6 +17802,8 @@ func (ec *executionContext) fieldContext_UpdateVendorPayload_vendor(_ context.Co return ec.fieldContext_Vendor_name(ctx, field) case "description": return ec.fieldContext_Vendor_description(ctx, field) + case "complianceReports": + return ec.fieldContext_Vendor_complianceReports(ctx, field) case "serviceStartAt": return ec.fieldContext_Vendor_serviceStartAt(ctx, field) case "serviceTerminationAt": @@ -17252,6 +17829,56 @@ func (ec *executionContext) fieldContext_UpdateVendorPayload_vendor(_ context.Co return fc, nil } +func (ec *executionContext) _UploadVendorComplianceReportPayload_vendorComplianceReportEdge(ctx context.Context, field graphql.CollectedField, obj *types.UploadVendorComplianceReportPayload) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_UploadVendorComplianceReportPayload_vendorComplianceReportEdge(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.VendorComplianceReportEdge, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.VendorComplianceReportEdge) + fc.Result = res + return ec.marshalNVendorComplianceReportEdge2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorComplianceReportEdge(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_UploadVendorComplianceReportPayload_vendorComplianceReportEdge(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "UploadVendorComplianceReportPayload", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "cursor": + return ec.fieldContext_VendorComplianceReportEdge_cursor(ctx, field) + case "node": + return ec.fieldContext_VendorComplianceReportEdge_node(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type VendorComplianceReportEdge", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _User_id(ctx context.Context, field graphql.CollectedField, obj *types.User) (ret graphql.Marshaler) { fc, err := ec.fieldContext_User_id(ctx, field) if err != nil { @@ -17808,6 +18435,67 @@ func (ec *executionContext) fieldContext_Vendor_description(_ context.Context, f return fc, nil } +func (ec *executionContext) _Vendor_complianceReports(ctx context.Context, field graphql.CollectedField, obj *types.Vendor) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Vendor_complianceReports(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Vendor().ComplianceReports(rctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*page.CursorKey), fc.Args["last"].(*int), fc.Args["before"].(*page.CursorKey), fc.Args["orderBy"].(*types.VendorComplianceReportOrderBy)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.VendorComplianceReportConnection) + fc.Result = res + return ec.marshalNVendorComplianceReportConnection2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorComplianceReportConnection(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Vendor_complianceReports(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Vendor", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "edges": + return ec.fieldContext_VendorComplianceReportConnection_edges(ctx, field) + case "pageInfo": + return ec.fieldContext_VendorComplianceReportConnection_pageInfo(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type VendorComplianceReportConnection", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Vendor_complianceReports_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _Vendor_serviceStartAt(ctx context.Context, field graphql.CollectedField, obj *types.Vendor) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Vendor_serviceStartAt(ctx, field) if err != nil { @@ -18192,6 +18880,639 @@ func (ec *executionContext) fieldContext_Vendor_updatedAt(_ context.Context, fie return fc, nil } +func (ec *executionContext) _VendorComplianceReport_id(ctx context.Context, field graphql.CollectedField, obj *types.VendorComplianceReport) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorComplianceReport_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(gid.GID) + fc.Result = res + return ec.marshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorComplianceReport_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorComplianceReport", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorComplianceReport_vendor(ctx context.Context, field graphql.CollectedField, obj *types.VendorComplianceReport) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorComplianceReport_vendor(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.VendorComplianceReport().Vendor(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.Vendor) + fc.Result = res + return ec.marshalNVendor2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendor(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorComplianceReport_vendor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorComplianceReport", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Vendor_id(ctx, field) + case "name": + return ec.fieldContext_Vendor_name(ctx, field) + case "description": + return ec.fieldContext_Vendor_description(ctx, field) + case "complianceReports": + return ec.fieldContext_Vendor_complianceReports(ctx, field) + case "serviceStartAt": + return ec.fieldContext_Vendor_serviceStartAt(ctx, field) + case "serviceTerminationAt": + return ec.fieldContext_Vendor_serviceTerminationAt(ctx, field) + case "serviceCriticality": + return ec.fieldContext_Vendor_serviceCriticality(ctx, field) + case "riskTier": + return ec.fieldContext_Vendor_riskTier(ctx, field) + case "statusPageUrl": + return ec.fieldContext_Vendor_statusPageUrl(ctx, field) + case "termsOfServiceUrl": + return ec.fieldContext_Vendor_termsOfServiceUrl(ctx, field) + case "privacyPolicyUrl": + return ec.fieldContext_Vendor_privacyPolicyUrl(ctx, field) + case "createdAt": + return ec.fieldContext_Vendor_createdAt(ctx, field) + case "updatedAt": + return ec.fieldContext_Vendor_updatedAt(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Vendor", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorComplianceReport_reportDate(ctx context.Context, field graphql.CollectedField, obj *types.VendorComplianceReport) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorComplianceReport_reportDate(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ReportDate, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(time.Time) + fc.Result = res + return ec.marshalNDatetime2timeᚐTime(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorComplianceReport_reportDate(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorComplianceReport", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Datetime does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorComplianceReport_validUntil(ctx context.Context, field graphql.CollectedField, obj *types.VendorComplianceReport) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorComplianceReport_validUntil(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ValidUntil, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*time.Time) + fc.Result = res + return ec.marshalODatetime2ᚖtimeᚐTime(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorComplianceReport_validUntil(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorComplianceReport", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Datetime does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorComplianceReport_reportName(ctx context.Context, field graphql.CollectedField, obj *types.VendorComplianceReport) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorComplianceReport_reportName(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.ReportName, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorComplianceReport_reportName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorComplianceReport", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorComplianceReport_fileUrl(ctx context.Context, field graphql.CollectedField, obj *types.VendorComplianceReport) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorComplianceReport_fileUrl(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.VendorComplianceReport().FileURL(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorComplianceReport_fileUrl(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorComplianceReport", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorComplianceReport_fileSize(ctx context.Context, field graphql.CollectedField, obj *types.VendorComplianceReport) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorComplianceReport_fileSize(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.FileSize, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorComplianceReport_fileSize(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorComplianceReport", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorComplianceReport_createdAt(ctx context.Context, field graphql.CollectedField, obj *types.VendorComplianceReport) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorComplianceReport_createdAt(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.CreatedAt, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(time.Time) + fc.Result = res + return ec.marshalNDatetime2timeᚐTime(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorComplianceReport_createdAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorComplianceReport", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Datetime does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorComplianceReport_updatedAt(ctx context.Context, field graphql.CollectedField, obj *types.VendorComplianceReport) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorComplianceReport_updatedAt(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.UpdatedAt, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(time.Time) + fc.Result = res + return ec.marshalNDatetime2timeᚐTime(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorComplianceReport_updatedAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorComplianceReport", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Datetime does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorComplianceReportConnection_edges(ctx context.Context, field graphql.CollectedField, obj *types.VendorComplianceReportConnection) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorComplianceReportConnection_edges(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Edges, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*types.VendorComplianceReportEdge) + fc.Result = res + return ec.marshalNVendorComplianceReportEdge2ᚕᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorComplianceReportEdgeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorComplianceReportConnection_edges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorComplianceReportConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "cursor": + return ec.fieldContext_VendorComplianceReportEdge_cursor(ctx, field) + case "node": + return ec.fieldContext_VendorComplianceReportEdge_node(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type VendorComplianceReportEdge", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorComplianceReportConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *types.VendorComplianceReportConnection) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorComplianceReportConnection_pageInfo(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.PageInfo, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.PageInfo) + fc.Result = res + return ec.marshalNPageInfo2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐPageInfo(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorComplianceReportConnection_pageInfo(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorComplianceReportConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "hasNextPage": + return ec.fieldContext_PageInfo_hasNextPage(ctx, field) + case "hasPreviousPage": + return ec.fieldContext_PageInfo_hasPreviousPage(ctx, field) + case "startCursor": + return ec.fieldContext_PageInfo_startCursor(ctx, field) + case "endCursor": + return ec.fieldContext_PageInfo_endCursor(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type PageInfo", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorComplianceReportEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *types.VendorComplianceReportEdge) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorComplianceReportEdge_cursor(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Cursor, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(page.CursorKey) + fc.Result = res + return ec.marshalNCursorKey2githubᚗcomᚋgetproboᚋproboᚋpkgᚋpageᚐCursorKey(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorComplianceReportEdge_cursor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorComplianceReportEdge", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type CursorKey does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorComplianceReportEdge_node(ctx context.Context, field graphql.CollectedField, obj *types.VendorComplianceReportEdge) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorComplianceReportEdge_node(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.Node, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.VendorComplianceReport) + fc.Result = res + return ec.marshalNVendorComplianceReport2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorComplianceReport(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorComplianceReportEdge_node(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorComplianceReportEdge", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_VendorComplianceReport_id(ctx, field) + case "vendor": + return ec.fieldContext_VendorComplianceReport_vendor(ctx, field) + case "reportDate": + return ec.fieldContext_VendorComplianceReport_reportDate(ctx, field) + case "validUntil": + return ec.fieldContext_VendorComplianceReport_validUntil(ctx, field) + case "reportName": + return ec.fieldContext_VendorComplianceReport_reportName(ctx, field) + case "fileUrl": + return ec.fieldContext_VendorComplianceReport_fileUrl(ctx, field) + case "fileSize": + return ec.fieldContext_VendorComplianceReport_fileSize(ctx, field) + case "createdAt": + return ec.fieldContext_VendorComplianceReport_createdAt(ctx, field) + case "updatedAt": + return ec.fieldContext_VendorComplianceReport_updatedAt(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type VendorComplianceReport", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _VendorConnection_edges(ctx context.Context, field graphql.CollectedField, obj *types.VendorConnection) (ret graphql.Marshaler) { fc, err := ec.fieldContext_VendorConnection_edges(ctx, field) if err != nil { @@ -18385,6 +19706,8 @@ func (ec *executionContext) fieldContext_VendorEdge_node(_ context.Context, fiel return ec.fieldContext_Vendor_name(ctx, field) case "description": return ec.fieldContext_Vendor_description(ctx, field) + case "complianceReports": + return ec.fieldContext_Vendor_complianceReports(ctx, field) case "serviceStartAt": return ec.fieldContext_Vendor_serviceStartAt(ctx, field) case "serviceTerminationAt": @@ -21526,6 +22849,33 @@ func (ec *executionContext) unmarshalInputDeleteTaskInput(ctx context.Context, o return it, nil } +func (ec *executionContext) unmarshalInputDeleteVendorComplianceReportInput(ctx context.Context, obj any) (types.DeleteVendorComplianceReportInput, error) { + var it types.DeleteVendorComplianceReportInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"reportId"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "reportId": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("reportId")) + data, err := ec.unmarshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v) + if err != nil { + return it, err + } + it.ReportID = data + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputDeleteVendorInput(ctx context.Context, obj any) (types.DeleteVendorInput, error) { var it types.DeleteVendorInput asMap := map[string]any{} @@ -22552,6 +23902,61 @@ func (ec *executionContext) unmarshalInputUpdateVendorInput(ctx context.Context, return it, nil } +func (ec *executionContext) unmarshalInputUploadVendorComplianceReportInput(ctx context.Context, obj any) (types.UploadVendorComplianceReportInput, error) { + var it types.UploadVendorComplianceReportInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"vendorId", "reportDate", "validUntil", "reportName", "file"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "vendorId": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("vendorId")) + data, err := ec.unmarshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v) + if err != nil { + return it, err + } + it.VendorID = data + case "reportDate": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("reportDate")) + data, err := ec.unmarshalNDatetime2timeᚐTime(ctx, v) + if err != nil { + return it, err + } + it.ReportDate = data + case "validUntil": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("validUntil")) + data, err := ec.unmarshalODatetime2ᚖtimeᚐTime(ctx, v) + if err != nil { + return it, err + } + it.ValidUntil = data + case "reportName": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("reportName")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.ReportName = data + case "file": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("file")) + data, err := ec.unmarshalNUpload2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚐUpload(ctx, v) + if err != nil { + return it, err + } + it.File = data + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputUserOrder(ctx context.Context, obj any) (types.UserOrderBy, error) { var it types.UserOrderBy asMap := map[string]any{} @@ -22586,6 +23991,40 @@ func (ec *executionContext) unmarshalInputUserOrder(ctx context.Context, obj any return it, nil } +func (ec *executionContext) unmarshalInputVendorComplianceReportOrder(ctx context.Context, obj any) (types.VendorComplianceReportOrderBy, error) { + var it types.VendorComplianceReportOrderBy + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"direction", "field"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "direction": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("direction")) + data, err := ec.unmarshalNOrderDirection2githubᚗcomᚋgetproboᚋproboᚋpkgᚋpageᚐOrderDirection(ctx, v) + if err != nil { + return it, err + } + it.Direction = data + case "field": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("field")) + data, err := ec.unmarshalNVendorComplianceReportOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐVendorComplianceReportOrderField(ctx, v) + if err != nil { + return it, err + } + it.Field = data + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputVendorOrder(ctx context.Context, obj any) (types.VendorOrderBy, error) { var it types.VendorOrderBy asMap := map[string]any{} @@ -22656,6 +24095,13 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj return graphql.Null } return ec._Vendor(ctx, sel, obj) + case types.VendorComplianceReport: + return ec._VendorComplianceReport(ctx, sel, &obj) + case *types.VendorComplianceReport: + if obj == nil { + return graphql.Null + } + return ec._VendorComplianceReport(ctx, sel, obj) case types.Framework: return ec._Framework(ctx, sel, &obj) case *types.Framework: @@ -23874,6 +25320,45 @@ func (ec *executionContext) _DeleteTaskPayload(ctx context.Context, sel ast.Sele return out } +var deleteVendorComplianceReportPayloadImplementors = []string{"DeleteVendorComplianceReportPayload"} + +func (ec *executionContext) _DeleteVendorComplianceReportPayload(ctx context.Context, sel ast.SelectionSet, obj *types.DeleteVendorComplianceReportPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, deleteVendorComplianceReportPayloadImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("DeleteVendorComplianceReportPayload") + case "deletedVendorComplianceReportId": + out.Values[i] = ec._DeleteVendorComplianceReportPayload_deletedVendorComplianceReportId(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + var deleteVendorPayloadImplementors = []string{"DeleteVendorPayload"} func (ec *executionContext) _DeleteVendorPayload(ctx context.Context, sel ast.SelectionSet, obj *types.DeleteVendorPayload) graphql.Marshaler { @@ -25002,6 +26487,20 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) if out.Values[i] == graphql.Null { out.Invalids++ } + case "uploadVendorComplianceReport": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_uploadVendorComplianceReport(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deleteVendorComplianceReport": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_deleteVendorComplianceReport(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } case "createPolicy": out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { return ec._Mutation_createPolicy(ctx, field) @@ -26887,6 +28386,45 @@ func (ec *executionContext) _UpdateVendorPayload(ctx context.Context, sel ast.Se return out } +var uploadVendorComplianceReportPayloadImplementors = []string{"UploadVendorComplianceReportPayload"} + +func (ec *executionContext) _UploadVendorComplianceReportPayload(ctx context.Context, sel ast.SelectionSet, obj *types.UploadVendorComplianceReportPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, uploadVendorComplianceReportPayloadImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("UploadVendorComplianceReportPayload") + case "vendorComplianceReportEdge": + out.Values[i] = ec._UploadVendorComplianceReportPayload_vendorComplianceReportEdge(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + var userImplementors = []string{"User", "Node"} func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj *types.User) graphql.Marshaler { @@ -27048,34 +28586,70 @@ func (ec *executionContext) _Vendor(ctx context.Context, sel ast.SelectionSet, o case "id": out.Values[i] = ec._Vendor_id(ctx, field, obj) if out.Values[i] == graphql.Null { - out.Invalids++ + atomic.AddUint32(&out.Invalids, 1) } case "name": out.Values[i] = ec._Vendor_name(ctx, field, obj) if out.Values[i] == graphql.Null { - out.Invalids++ + atomic.AddUint32(&out.Invalids, 1) } case "description": out.Values[i] = ec._Vendor_description(ctx, field, obj) if out.Values[i] == graphql.Null { - out.Invalids++ + atomic.AddUint32(&out.Invalids, 1) } + case "complianceReports": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Vendor_complianceReports(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) case "serviceStartAt": out.Values[i] = ec._Vendor_serviceStartAt(ctx, field, obj) if out.Values[i] == graphql.Null { - out.Invalids++ + atomic.AddUint32(&out.Invalids, 1) } case "serviceTerminationAt": out.Values[i] = ec._Vendor_serviceTerminationAt(ctx, field, obj) case "serviceCriticality": out.Values[i] = ec._Vendor_serviceCriticality(ctx, field, obj) if out.Values[i] == graphql.Null { - out.Invalids++ + atomic.AddUint32(&out.Invalids, 1) } case "riskTier": out.Values[i] = ec._Vendor_riskTier(ctx, field, obj) if out.Values[i] == graphql.Null { - out.Invalids++ + atomic.AddUint32(&out.Invalids, 1) } case "statusPageUrl": out.Values[i] = ec._Vendor_statusPageUrl(ctx, field, obj) @@ -27086,10 +28660,236 @@ func (ec *executionContext) _Vendor(ctx context.Context, sel ast.SelectionSet, o case "createdAt": out.Values[i] = ec._Vendor_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { - out.Invalids++ + atomic.AddUint32(&out.Invalids, 1) } case "updatedAt": out.Values[i] = ec._Vendor_updatedAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var vendorComplianceReportImplementors = []string{"VendorComplianceReport", "Node"} + +func (ec *executionContext) _VendorComplianceReport(ctx context.Context, sel ast.SelectionSet, obj *types.VendorComplianceReport) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, vendorComplianceReportImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("VendorComplianceReport") + case "id": + out.Values[i] = ec._VendorComplianceReport_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "vendor": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._VendorComplianceReport_vendor(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "reportDate": + out.Values[i] = ec._VendorComplianceReport_reportDate(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "validUntil": + out.Values[i] = ec._VendorComplianceReport_validUntil(ctx, field, obj) + case "reportName": + out.Values[i] = ec._VendorComplianceReport_reportName(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "fileUrl": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._VendorComplianceReport_fileUrl(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "fileSize": + out.Values[i] = ec._VendorComplianceReport_fileSize(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "createdAt": + out.Values[i] = ec._VendorComplianceReport_createdAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "updatedAt": + out.Values[i] = ec._VendorComplianceReport_updatedAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var vendorComplianceReportConnectionImplementors = []string{"VendorComplianceReportConnection"} + +func (ec *executionContext) _VendorComplianceReportConnection(ctx context.Context, sel ast.SelectionSet, obj *types.VendorComplianceReportConnection) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, vendorComplianceReportConnectionImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("VendorComplianceReportConnection") + case "edges": + out.Values[i] = ec._VendorComplianceReportConnection_edges(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "pageInfo": + out.Values[i] = ec._VendorComplianceReportConnection_pageInfo(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var vendorComplianceReportEdgeImplementors = []string{"VendorComplianceReportEdge"} + +func (ec *executionContext) _VendorComplianceReportEdge(ctx context.Context, sel ast.SelectionSet, obj *types.VendorComplianceReportEdge) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, vendorComplianceReportEdgeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("VendorComplianceReportEdge") + case "cursor": + out.Values[i] = ec._VendorComplianceReportEdge_cursor(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "node": + out.Values[i] = ec._VendorComplianceReportEdge_node(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } @@ -28223,6 +30023,25 @@ func (ec *executionContext) marshalNDeleteTaskPayload2ᚖgithubᚗcomᚋgetprobo return ec._DeleteTaskPayload(ctx, sel, v) } +func (ec *executionContext) unmarshalNDeleteVendorComplianceReportInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteVendorComplianceReportInput(ctx context.Context, v any) (types.DeleteVendorComplianceReportInput, error) { + res, err := ec.unmarshalInputDeleteVendorComplianceReportInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNDeleteVendorComplianceReportPayload2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteVendorComplianceReportPayload(ctx context.Context, sel ast.SelectionSet, v types.DeleteVendorComplianceReportPayload) graphql.Marshaler { + return ec._DeleteVendorComplianceReportPayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNDeleteVendorComplianceReportPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteVendorComplianceReportPayload(ctx context.Context, sel ast.SelectionSet, v *types.DeleteVendorComplianceReportPayload) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._DeleteVendorComplianceReportPayload(ctx, sel, v) +} + func (ec *executionContext) unmarshalNDeleteVendorInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteVendorInput(ctx context.Context, v any) (types.DeleteVendorInput, error) { res, err := ec.unmarshalInputDeleteVendorInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) @@ -29724,6 +31543,25 @@ func (ec *executionContext) marshalNUpload2githubᚗcomᚋ99designsᚋgqlgenᚋg return res } +func (ec *executionContext) unmarshalNUploadVendorComplianceReportInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUploadVendorComplianceReportInput(ctx context.Context, v any) (types.UploadVendorComplianceReportInput, error) { + res, err := ec.unmarshalInputUploadVendorComplianceReportInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNUploadVendorComplianceReportPayload2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUploadVendorComplianceReportPayload(ctx context.Context, sel ast.SelectionSet, v types.UploadVendorComplianceReportPayload) graphql.Marshaler { + return ec._UploadVendorComplianceReportPayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNUploadVendorComplianceReportPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUploadVendorComplianceReportPayload(ctx context.Context, sel ast.SelectionSet, v *types.UploadVendorComplianceReportPayload) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._UploadVendorComplianceReportPayload(ctx, sel, v) +} + func (ec *executionContext) marshalNUser2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUser(ctx context.Context, sel ast.SelectionSet, v *types.User) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { @@ -29827,6 +31665,10 @@ var ( } ) +func (ec *executionContext) marshalNVendor2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendor(ctx context.Context, sel ast.SelectionSet, v types.Vendor) graphql.Marshaler { + return ec._Vendor(ctx, sel, &v) +} + func (ec *executionContext) marshalNVendor2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendor(ctx context.Context, sel ast.SelectionSet, v *types.Vendor) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { @@ -29837,6 +31679,111 @@ func (ec *executionContext) marshalNVendor2ᚖgithubᚗcomᚋgetproboᚋproboᚋ return ec._Vendor(ctx, sel, v) } +func (ec *executionContext) marshalNVendorComplianceReport2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorComplianceReport(ctx context.Context, sel ast.SelectionSet, v *types.VendorComplianceReport) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._VendorComplianceReport(ctx, sel, v) +} + +func (ec *executionContext) marshalNVendorComplianceReportConnection2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorComplianceReportConnection(ctx context.Context, sel ast.SelectionSet, v types.VendorComplianceReportConnection) graphql.Marshaler { + return ec._VendorComplianceReportConnection(ctx, sel, &v) +} + +func (ec *executionContext) marshalNVendorComplianceReportConnection2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorComplianceReportConnection(ctx context.Context, sel ast.SelectionSet, v *types.VendorComplianceReportConnection) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._VendorComplianceReportConnection(ctx, sel, v) +} + +func (ec *executionContext) marshalNVendorComplianceReportEdge2ᚕᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorComplianceReportEdgeᚄ(ctx context.Context, sel ast.SelectionSet, v []*types.VendorComplianceReportEdge) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNVendorComplianceReportEdge2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorComplianceReportEdge(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNVendorComplianceReportEdge2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorComplianceReportEdge(ctx context.Context, sel ast.SelectionSet, v *types.VendorComplianceReportEdge) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._VendorComplianceReportEdge(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNVendorComplianceReportOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐVendorComplianceReportOrderField(ctx context.Context, v any) (coredata.VendorComplianceReportOrderField, error) { + tmp, err := graphql.UnmarshalString(v) + res := unmarshalNVendorComplianceReportOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐVendorComplianceReportOrderField[tmp] + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNVendorComplianceReportOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐVendorComplianceReportOrderField(ctx context.Context, sel ast.SelectionSet, v coredata.VendorComplianceReportOrderField) graphql.Marshaler { + res := graphql.MarshalString(marshalNVendorComplianceReportOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐVendorComplianceReportOrderField[v]) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +var ( + unmarshalNVendorComplianceReportOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐVendorComplianceReportOrderField = map[string]coredata.VendorComplianceReportOrderField{ + "REPORT_DATE": coredata.VendorComplianceReportOrderFieldReportDate, + "CREATED_AT": coredata.VendorComplianceReportOrderFieldCreatedAt, + } + marshalNVendorComplianceReportOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐVendorComplianceReportOrderField = map[coredata.VendorComplianceReportOrderField]string{ + coredata.VendorComplianceReportOrderFieldReportDate: "REPORT_DATE", + coredata.VendorComplianceReportOrderFieldCreatedAt: "CREATED_AT", + } +) + func (ec *executionContext) marshalNVendorConnection2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorConnection(ctx context.Context, sel ast.SelectionSet, v types.VendorConnection) graphql.Marshaler { return ec._VendorConnection(ctx, sel, &v) } @@ -30675,6 +32622,14 @@ func (ec *executionContext) unmarshalOUserOrder2ᚖgithubᚗcomᚋgetproboᚋpro return &res, graphql.ErrorOnPath(ctx, err) } +func (ec *executionContext) unmarshalOVendorComplianceReportOrder2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorComplianceReportOrderBy(ctx context.Context, v any) (*types.VendorComplianceReportOrderBy, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputVendorComplianceReportOrder(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) unmarshalOVendorOrder2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorOrderBy(ctx context.Context, v any) (*types.VendorOrderBy, error) { if v == nil { return nil, nil diff --git a/pkg/server/api/console/v1/types/types.go b/pkg/server/api/console/v1/types/types.go index 0fb9e8acf..bf71054ad 100644 --- a/pkg/server/api/console/v1/types/types.go +++ b/pkg/server/api/console/v1/types/types.go @@ -281,6 +281,14 @@ type DeleteTaskPayload struct { DeletedTaskID gid.GID `json:"deletedTaskId"` } +type DeleteVendorComplianceReportInput struct { + ReportID gid.GID `json:"reportId"` +} + +type DeleteVendorComplianceReportPayload struct { + DeletedVendorComplianceReportID gid.GID `json:"deletedVendorComplianceReportId"` +} + type DeleteVendorInput struct { VendorID gid.GID `json:"vendorId"` } @@ -679,6 +687,18 @@ type UpdateVendorPayload struct { Vendor *Vendor `json:"vendor"` } +type UploadVendorComplianceReportInput struct { + VendorID gid.GID `json:"vendorId"` + ReportDate time.Time `json:"reportDate"` + ValidUntil *time.Time `json:"validUntil,omitempty"` + ReportName string `json:"reportName"` + File graphql.Upload `json:"file"` +} + +type UploadVendorComplianceReportPayload struct { + VendorComplianceReportEdge *VendorComplianceReportEdge `json:"vendorComplianceReportEdge"` +} + type User struct { ID gid.GID `json:"id"` FullName string `json:"fullName"` @@ -701,23 +721,49 @@ type UserEdge struct { } type Vendor struct { - ID gid.GID `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - ServiceStartAt time.Time `json:"serviceStartAt"` - ServiceTerminationAt *time.Time `json:"serviceTerminationAt,omitempty"` - ServiceCriticality coredata.ServiceCriticality `json:"serviceCriticality"` - RiskTier coredata.RiskTier `json:"riskTier"` - StatusPageURL *string `json:"statusPageUrl,omitempty"` - TermsOfServiceURL *string `json:"termsOfServiceUrl,omitempty"` - PrivacyPolicyURL *string `json:"privacyPolicyUrl,omitempty"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + ID gid.GID `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + ComplianceReports *VendorComplianceReportConnection `json:"complianceReports"` + ServiceStartAt time.Time `json:"serviceStartAt"` + ServiceTerminationAt *time.Time `json:"serviceTerminationAt,omitempty"` + ServiceCriticality coredata.ServiceCriticality `json:"serviceCriticality"` + RiskTier coredata.RiskTier `json:"riskTier"` + StatusPageURL *string `json:"statusPageUrl,omitempty"` + TermsOfServiceURL *string `json:"termsOfServiceUrl,omitempty"` + PrivacyPolicyURL *string `json:"privacyPolicyUrl,omitempty"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` } func (Vendor) IsNode() {} func (this Vendor) GetID() gid.GID { return this.ID } +type VendorComplianceReport struct { + ID gid.GID `json:"id"` + Vendor *Vendor `json:"vendor"` + ReportDate time.Time `json:"reportDate"` + ValidUntil *time.Time `json:"validUntil,omitempty"` + ReportName string `json:"reportName"` + FileURL string `json:"fileUrl"` + FileSize int `json:"fileSize"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` +} + +func (VendorComplianceReport) IsNode() {} +func (this VendorComplianceReport) GetID() gid.GID { return this.ID } + +type VendorComplianceReportConnection struct { + Edges []*VendorComplianceReportEdge `json:"edges"` + PageInfo *PageInfo `json:"pageInfo"` +} + +type VendorComplianceReportEdge struct { + Cursor page.CursorKey `json:"cursor"` + Node *VendorComplianceReport `json:"node"` +} + type VendorConnection struct { Edges []*VendorEdge `json:"edges"` PageInfo *PageInfo `json:"pageInfo"` diff --git a/pkg/server/api/console/v1/types/vendor_compliance_report.go b/pkg/server/api/console/v1/types/vendor_compliance_report.go new file mode 100644 index 000000000..352eb1a26 --- /dev/null +++ b/pkg/server/api/console/v1/types/vendor_compliance_report.go @@ -0,0 +1,56 @@ +// Copyright (c) 2025 Probo Inc . +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +package types + +import ( + "github.com/getprobo/probo/pkg/coredata" + "github.com/getprobo/probo/pkg/page" +) + +type ( + VendorComplianceReportOrderBy OrderBy[coredata.VendorComplianceReportOrderField] +) + +func NewVendorComplianceReportConnection(p *page.Page[*coredata.VendorComplianceReport, coredata.VendorComplianceReportOrderField]) *VendorComplianceReportConnection { + var edges = make([]*VendorComplianceReportEdge, len(p.Data)) + + for i := range edges { + edges[i] = NewVendorComplianceReportEdge(p.Data[i], p.Cursor.OrderBy.Field) + } + + return &VendorComplianceReportConnection{ + Edges: edges, + PageInfo: NewPageInfo(p), + } +} + +func NewVendorComplianceReportEdge(c *coredata.VendorComplianceReport, orderBy coredata.VendorComplianceReportOrderField) *VendorComplianceReportEdge { + return &VendorComplianceReportEdge{ + Cursor: c.CursorKey(orderBy), + Node: NewVendorComplianceReport(c), + } +} + +func NewVendorComplianceReport(c *coredata.VendorComplianceReport) *VendorComplianceReport { + return &VendorComplianceReport{ + ID: c.ID, + ReportDate: c.ReportDate, + ValidUntil: c.ValidUntil, + ReportName: c.ReportName, + FileSize: c.FileSize, + CreatedAt: c.CreatedAt, + UpdatedAt: c.UpdatedAt, + } +} diff --git a/pkg/server/api/console/v1/v1_resolver.go b/pkg/server/api/console/v1/v1_resolver.go index e6254dc5b..2ac772167 100644 --- a/pkg/server/api/console/v1/v1_resolver.go +++ b/pkg/server/api/console/v1/v1_resolver.go @@ -866,6 +866,43 @@ func (r *mutationResolver) DeleteEvidence(ctx context.Context, input types.Delet }, nil } +// UploadVendorComplianceReport is the resolver for the uploadVendorComplianceReport field. +func (r *mutationResolver) UploadVendorComplianceReport(ctx context.Context, input types.UploadVendorComplianceReportInput) (*types.UploadVendorComplianceReportPayload, error) { + svc := r.GetTenantServiceIfAuthorized(ctx, input.VendorID.TenantID()) + + vendorComplianceReport, err := svc.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) { + svc := r.GetTenantServiceIfAuthorized(ctx, input.ReportID.TenantID()) + + err := svc.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 +} + // CreatePolicy is the resolver for the createPolicy field. func (r *mutationResolver) CreatePolicy(ctx context.Context, input types.CreatePolicyInput) (*types.CreatePolicyPayload, error) { svc := r.GetTenantServiceIfAuthorized(ctx, input.OrganizationID.TenantID()) @@ -1218,6 +1255,12 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error panic(fmt.Errorf("cannot get risk: %w", err)) } return types.NewRisk(risk), nil + case coredata.VendorComplianceReportEntityType: + vendorComplianceReport, err := svc.VendorComplianceReports.Get(ctx, id) + if err != nil { + panic(fmt.Errorf("cannot get vendor compliance report: %w", err)) + } + return types.NewVendorComplianceReport(vendorComplianceReport), nil default: } @@ -1305,6 +1348,55 @@ func (r *taskResolver) Evidences(ctx context.Context, obj *types.Task, first *in return types.NewEvidenceConnection(page), 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 := r.GetTenantServiceIfAuthorized(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 := svc.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 +} + +// Vendor is the resolver for the vendor field. +func (r *vendorComplianceReportResolver) Vendor(ctx context.Context, obj *types.VendorComplianceReport) (*types.Vendor, error) { + svc := r.GetTenantServiceIfAuthorized(ctx, obj.ID.TenantID()) + + vendor, err := svc.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) { + svc := r.GetTenantServiceIfAuthorized(ctx, obj.ID.TenantID()) + + fileURL, err := svc.VendorComplianceReports.GenerateFileURL(ctx, obj.ID, 1*time.Hour) + if err != nil { + panic(fmt.Errorf("failed to generate file URL: %w", err)) + } + + return fileURL, 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) @@ -1360,6 +1452,14 @@ func (r *Resolver) Risk() schema.RiskResolver { return &riskResolver{r} } // Task returns schema.TaskResolver implementation. func (r *Resolver) Task() schema.TaskResolver { return &taskResolver{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} +} + // Viewer returns schema.ViewerResolver implementation. func (r *Resolver) Viewer() schema.ViewerResolver { return &viewerResolver{r} } @@ -1373,4 +1473,6 @@ type policyResolver struct{ *Resolver } type queryResolver struct{ *Resolver } type riskResolver struct{ *Resolver } type taskResolver struct{ *Resolver } +type vendorResolver struct{ *Resolver } +type vendorComplianceReportResolver struct{ *Resolver } type viewerResolver struct{ *Resolver }