File refs in one table
Added a file service Refactored evidence and vendor compliance associated services and resolvers Created SQL migration scripts Updated GraphQL schema accordingly and the UI components Removed unused methods and resolvers for evidence service Signed-off-by: Yannis Varni <yannis@edinomis.fr>
This commit is contained in:
committed by
Sacha Al Himdani
parent
3822b1916c
commit
ff7ba08fc1
@@ -1755,8 +1755,7 @@ type VendorComplianceReport implements Node {
|
||||
reportDate: Datetime!
|
||||
validUntil: Datetime
|
||||
reportName: String!
|
||||
fileUrl: String! @goField(forceResolver: true)
|
||||
fileSize: BigInt!
|
||||
file: File @goField(forceResolver: true)
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
}
|
||||
@@ -1944,12 +1943,10 @@ type Task implements Node {
|
||||
|
||||
type Evidence implements Node {
|
||||
id: ID!
|
||||
fileUrl: String @goField(forceResolver: true)
|
||||
mimeType: String!
|
||||
size: Int!
|
||||
state: EvidenceState!
|
||||
type: EvidenceType!
|
||||
filename: String!
|
||||
file: File @goField(forceResolver: true)
|
||||
url: String
|
||||
description: String!
|
||||
|
||||
@@ -2590,6 +2587,16 @@ type SnapshotEdge {
|
||||
node: Snapshot!
|
||||
}
|
||||
|
||||
type File {
|
||||
id: ID!
|
||||
mimeType: String!
|
||||
fileName: String!
|
||||
size: BigInt!
|
||||
downloadUrl: String! @goField(forceResolver: true)
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
}
|
||||
|
||||
# Root Types
|
||||
type Query {
|
||||
node(id: ID!): Node!
|
||||
@@ -2751,12 +2758,7 @@ type Mutation {
|
||||
): DeleteRiskObligationMappingPayload!
|
||||
|
||||
# Evidence mutations
|
||||
requestEvidence(input: RequestEvidenceInput!): RequestEvidencePayload!
|
||||
fulfillEvidence(input: FulfillEvidenceInput!): FulfillEvidencePayload!
|
||||
deleteEvidence(input: DeleteEvidenceInput!): DeleteEvidencePayload!
|
||||
uploadTaskEvidence(
|
||||
input: UploadTaskEvidenceInput!
|
||||
): UploadTaskEvidencePayload!
|
||||
uploadMeasureEvidence(
|
||||
input: UploadMeasureEvidenceInput!
|
||||
): UploadMeasureEvidencePayload!
|
||||
@@ -4142,19 +4144,10 @@ type CancelSignatureRequestPayload {
|
||||
deletedDocumentVersionSignatureId: ID!
|
||||
}
|
||||
|
||||
type UploadTaskEvidencePayload {
|
||||
evidenceEdge: EvidenceEdge!
|
||||
}
|
||||
|
||||
type UploadMeasureEvidencePayload {
|
||||
evidenceEdge: EvidenceEdge!
|
||||
}
|
||||
|
||||
input UploadTaskEvidenceInput {
|
||||
taskId: ID!
|
||||
file: Upload!
|
||||
}
|
||||
|
||||
input UploadMeasureEvidenceInput {
|
||||
measureId: ID!
|
||||
file: Upload!
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -61,8 +61,6 @@ func NewEvidenceEdge(e *coredata.Evidence, orderBy coredata.EvidenceOrderField)
|
||||
}
|
||||
|
||||
func NewEvidence(e *coredata.Evidence) *Evidence {
|
||||
var fileURL *string = nil
|
||||
|
||||
var urlPtr *string = nil
|
||||
if e.URL != "" {
|
||||
urlCopy := e.URL
|
||||
@@ -73,10 +71,6 @@ func NewEvidence(e *coredata.Evidence) *Evidence {
|
||||
ID: e.ID,
|
||||
State: e.State,
|
||||
Type: e.Type,
|
||||
FileURL: fileURL,
|
||||
Filename: e.Filename,
|
||||
MimeType: e.MimeType,
|
||||
Size: int(e.Size),
|
||||
URL: urlPtr,
|
||||
Description: e.Description,
|
||||
CreatedAt: e.CreatedAt,
|
||||
|
||||
30
pkg/server/api/console/v1/types/file.go
Normal file
30
pkg/server/api/console/v1/types/file.go
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// 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"
|
||||
)
|
||||
|
||||
func NewFile(r *coredata.File) *File {
|
||||
return &File{
|
||||
ID: r.ID,
|
||||
MimeType: r.MimeType,
|
||||
FileName: r.FileName,
|
||||
Size: r.FileSize,
|
||||
CreatedAt: r.CreatedAt,
|
||||
UpdatedAt: r.UpdatedAt,
|
||||
}
|
||||
}
|
||||
@@ -1034,12 +1034,10 @@ type DocumentVersionSignatureOrder struct {
|
||||
|
||||
type Evidence struct {
|
||||
ID gid.GID `json:"id"`
|
||||
FileURL *string `json:"fileUrl,omitempty"`
|
||||
MimeType string `json:"mimeType"`
|
||||
Size int `json:"size"`
|
||||
State coredata.EvidenceState `json:"state"`
|
||||
Type coredata.EvidenceType `json:"type"`
|
||||
Filename string `json:"filename"`
|
||||
File *File `json:"file,omitempty"`
|
||||
URL *string `json:"url,omitempty"`
|
||||
Description string `json:"description"`
|
||||
Task *Task `json:"task,omitempty"`
|
||||
@@ -1075,6 +1073,16 @@ type ExportFrameworkPayload struct {
|
||||
ExportJobID gid.GID `json:"exportJobId"`
|
||||
}
|
||||
|
||||
type File struct {
|
||||
ID gid.GID `json:"id"`
|
||||
MimeType string `json:"mimeType"`
|
||||
FileName string `json:"fileName"`
|
||||
Size int64 `json:"size"`
|
||||
DownloadURL string `json:"downloadUrl"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type Framework struct {
|
||||
ID gid.GID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
@@ -1955,15 +1963,6 @@ type UploadMeasureEvidencePayload struct {
|
||||
EvidenceEdge *EvidenceEdge `json:"evidenceEdge"`
|
||||
}
|
||||
|
||||
type UploadTaskEvidenceInput struct {
|
||||
TaskID gid.GID `json:"taskId"`
|
||||
File graphql.Upload `json:"file"`
|
||||
}
|
||||
|
||||
type UploadTaskEvidencePayload struct {
|
||||
EvidenceEdge *EvidenceEdge `json:"evidenceEdge"`
|
||||
}
|
||||
|
||||
type UploadTrustCenterNDAInput struct {
|
||||
TrustCenterID gid.GID `json:"trustCenterId"`
|
||||
FileName string `json:"fileName"`
|
||||
@@ -2090,8 +2089,7 @@ type VendorComplianceReport struct {
|
||||
ReportDate time.Time `json:"reportDate"`
|
||||
ValidUntil *time.Time `json:"validUntil,omitempty"`
|
||||
ReportName string `json:"reportName"`
|
||||
FileURL string `json:"fileUrl"`
|
||||
FileSize int64 `json:"fileSize"`
|
||||
File *File `json:"file,omitempty"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
@@ -49,7 +49,6 @@ func NewVendorComplianceReport(c *coredata.VendorComplianceReport) *VendorCompli
|
||||
ReportDate: c.ReportDate,
|
||||
ValidUntil: c.ValidUntil,
|
||||
ReportName: c.ReportName,
|
||||
FileSize: c.FileSize,
|
||||
CreatedAt: c.CreatedAt,
|
||||
UpdatedAt: c.UpdatedAt,
|
||||
}
|
||||
|
||||
@@ -734,21 +734,25 @@ func (r *documentVersionSignatureResolver) SignedBy(ctx context.Context, obj *ty
|
||||
return types.NewPeople(people), nil
|
||||
}
|
||||
|
||||
// FileURL is the resolver for the fileUrl field.
|
||||
func (r *evidenceResolver) FileURL(ctx context.Context, obj *types.Evidence) (*string, error) {
|
||||
// File is the resolver for the file field.
|
||||
func (r *evidenceResolver) File(ctx context.Context, obj *types.Evidence) (*types.File, error) {
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
if obj.Type == coredata.EvidenceTypeLink {
|
||||
return obj.URL, nil
|
||||
}
|
||||
|
||||
fileURL, err := prb.Evidences.GenerateFileURL(ctx, obj.ID, 15*time.Minute)
|
||||
evidence, err := prb.Evidences.Get(ctx, obj.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot generate file URL: %w", err)
|
||||
return nil, fmt.Errorf("cannot load evidence: %w", err)
|
||||
}
|
||||
|
||||
result := *fileURL
|
||||
return &result, nil
|
||||
if evidence.EvidenceFileId == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
file, err := prb.Files.Get(ctx, *evidence.EvidenceFileId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot load evidence file: %w", err)
|
||||
}
|
||||
|
||||
return types.NewFile(file), nil
|
||||
}
|
||||
|
||||
// Task is the resolver for the task field.
|
||||
@@ -811,6 +815,18 @@ func (r *evidenceConnectionResolver) TotalCount(ctx context.Context, obj *types.
|
||||
panic(fmt.Errorf("unsupported resolver: %T", obj.Resolver))
|
||||
}
|
||||
|
||||
// DownloadURL is the resolver for the downloadUrl field.
|
||||
func (r *fileResolver) DownloadURL(ctx context.Context, obj *types.File) (string, error) {
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
downloadUrl, err := prb.Files.GenerateFileTempURL(ctx, obj.ID, 60*time.Second)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("cannot generate download url: %w", err)
|
||||
}
|
||||
|
||||
return downloadUrl, nil
|
||||
}
|
||||
|
||||
// Organization is the resolver for the organization field.
|
||||
func (r *frameworkResolver) Organization(ctx context.Context, obj *types.Framework) (*types.Organization, error) {
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
@@ -2227,55 +2243,6 @@ func (r *mutationResolver) DeleteRiskObligationMapping(ctx context.Context, inpu
|
||||
}, nil
|
||||
}
|
||||
|
||||
// RequestEvidence is the resolver for the requestEvidence field.
|
||||
func (r *mutationResolver) RequestEvidence(ctx context.Context, input types.RequestEvidenceInput) (*types.RequestEvidencePayload, error) {
|
||||
prb := r.ProboService(ctx, input.TaskID.TenantID())
|
||||
|
||||
evidence, err := prb.Evidences.Request(
|
||||
ctx,
|
||||
probo.RequestEvidenceRequest{
|
||||
TaskID: &input.TaskID,
|
||||
Name: input.Name,
|
||||
Type: input.Type,
|
||||
Description: input.Description,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot request evidence: %w", err))
|
||||
}
|
||||
|
||||
return &types.RequestEvidencePayload{
|
||||
EvidenceEdge: types.NewEvidenceEdge(evidence, coredata.EvidenceOrderFieldCreatedAt),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FulfillEvidence is the resolver for the fulfillEvidence field.
|
||||
func (r *mutationResolver) FulfillEvidence(ctx context.Context, input types.FulfillEvidenceInput) (*types.FulfillEvidencePayload, error) {
|
||||
prb := r.ProboService(ctx, input.EvidenceID.TenantID())
|
||||
|
||||
req := probo.FulfilledEvidenceRequest{
|
||||
EvidenceID: input.EvidenceID,
|
||||
}
|
||||
|
||||
if input.File != nil {
|
||||
req.File = input.File.File
|
||||
req.Filename = &input.File.Filename
|
||||
}
|
||||
|
||||
if input.URL != nil {
|
||||
req.URL = input.URL
|
||||
}
|
||||
|
||||
evidence, err := prb.Evidences.Fulfill(ctx, req)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot fulfill evidence: %w", err))
|
||||
}
|
||||
|
||||
return &types.FulfillEvidencePayload{
|
||||
EvidenceEdge: types.NewEvidenceEdge(evidence, coredata.EvidenceOrderFieldCreatedAt),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteEvidence is the resolver for the deleteEvidence field.
|
||||
func (r *mutationResolver) DeleteEvidence(ctx context.Context, input types.DeleteEvidenceInput) (*types.DeleteEvidencePayload, error) {
|
||||
prb := r.ProboService(ctx, input.EvidenceID.TenantID())
|
||||
@@ -2290,31 +2257,6 @@ func (r *mutationResolver) DeleteEvidence(ctx context.Context, input types.Delet
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UploadTaskEvidence is the resolver for the uploadTaskEvidence field.
|
||||
func (r *mutationResolver) UploadTaskEvidence(ctx context.Context, input types.UploadTaskEvidenceInput) (*types.UploadTaskEvidencePayload, error) {
|
||||
prb := r.ProboService(ctx, input.TaskID.TenantID())
|
||||
|
||||
evidence, err := prb.Evidences.UploadTaskEvidence(
|
||||
ctx,
|
||||
probo.UploadTaskEvidenceRequest{
|
||||
TaskID: input.TaskID,
|
||||
File: probo.File{
|
||||
Content: input.File.File,
|
||||
Filename: input.File.Filename,
|
||||
Size: input.File.Size,
|
||||
ContentType: input.File.ContentType,
|
||||
},
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot upload task evidence: %w", err))
|
||||
}
|
||||
|
||||
return &types.UploadTaskEvidencePayload{
|
||||
EvidenceEdge: types.NewEvidenceEdge(evidence, coredata.EvidenceOrderFieldCreatedAt),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UploadMeasureEvidence is the resolver for the uploadMeasureEvidence field.
|
||||
func (r *mutationResolver) UploadMeasureEvidence(ctx context.Context, input types.UploadMeasureEvidenceInput) (*types.UploadMeasureEvidencePayload, error) {
|
||||
prb := r.ProboService(ctx, input.MeasureID.TenantID())
|
||||
@@ -2323,7 +2265,7 @@ func (r *mutationResolver) UploadMeasureEvidence(ctx context.Context, input type
|
||||
ctx,
|
||||
probo.UploadMeasureEvidenceRequest{
|
||||
MeasureID: input.MeasureID,
|
||||
File: probo.File{
|
||||
File: probo.FileUpload{
|
||||
Content: input.File.File,
|
||||
Filename: input.File.Filename,
|
||||
Size: input.File.Size,
|
||||
@@ -2348,7 +2290,7 @@ func (r *mutationResolver) UploadVendorComplianceReport(ctx context.Context, inp
|
||||
ctx,
|
||||
input.VendorID,
|
||||
&probo.VendorComplianceReportCreateRequest{
|
||||
File: input.File.File,
|
||||
File: probo.FileUpload{Filename: input.File.Filename, Size: input.File.Size, Content: input.File.File, ContentType: input.File.ContentType},
|
||||
ReportDate: input.ReportDate,
|
||||
ValidUntil: input.ValidUntil,
|
||||
ReportName: input.ReportName,
|
||||
@@ -5065,16 +5007,25 @@ func (r *vendorComplianceReportResolver) Vendor(ctx context.Context, obj *types.
|
||||
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) {
|
||||
// File is the resolver for the file field.
|
||||
func (r *vendorComplianceReportResolver) File(ctx context.Context, obj *types.VendorComplianceReport) (*types.File, error) {
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
fileURL, err := prb.VendorComplianceReports.GenerateFileURL(ctx, obj.ID, 1*time.Hour)
|
||||
evidence, err := prb.VendorComplianceReports.Get(ctx, obj.ID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to generate file URL: %w", err))
|
||||
return nil, fmt.Errorf("cannot load evidence: %w", err)
|
||||
}
|
||||
|
||||
return fileURL, nil
|
||||
if evidence.ReportFileId == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
file, err := prb.Files.Get(ctx, *evidence.ReportFileId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot load evidence file: %w", err)
|
||||
}
|
||||
|
||||
return types.NewFile(file), nil
|
||||
}
|
||||
|
||||
// TotalCount is the resolver for the totalCount field.
|
||||
@@ -5271,6 +5222,9 @@ func (r *Resolver) EvidenceConnection() schema.EvidenceConnectionResolver {
|
||||
return &evidenceConnectionResolver{r}
|
||||
}
|
||||
|
||||
// File returns schema.FileResolver implementation.
|
||||
func (r *Resolver) File() schema.FileResolver { return &fileResolver{r} }
|
||||
|
||||
// Framework returns schema.FrameworkResolver implementation.
|
||||
func (r *Resolver) Framework() schema.FrameworkResolver { return &frameworkResolver{r} }
|
||||
|
||||
@@ -5434,6 +5388,7 @@ type documentVersionResolver struct{ *Resolver }
|
||||
type documentVersionSignatureResolver struct{ *Resolver }
|
||||
type evidenceResolver struct{ *Resolver }
|
||||
type evidenceConnectionResolver struct{ *Resolver }
|
||||
type fileResolver struct{ *Resolver }
|
||||
type frameworkResolver struct{ *Resolver }
|
||||
type frameworkConnectionResolver struct{ *Resolver }
|
||||
type measureResolver struct{ *Resolver }
|
||||
|
||||
Reference in New Issue
Block a user