From f00a5169991427042dd6ca7287217e4fc84d17ac Mon Sep 17 00:00:00 2001 From: Bryan Frimin Date: Thu, 10 Jul 2025 12:28:10 +0200 Subject: [PATCH] Add bulk request signatures Signed-off-by: Bryan Frimin --- pkg/probo/document_service.go | 113 ++++++-- pkg/server/api/console/v1/schema.graphql | 12 + pkg/server/api/console/v1/schema/schema.go | 269 ++++++++++++++++++ .../v1/types/document_version_signature.go | 9 + pkg/server/api/console/v1/types/types.go | 9 + pkg/server/api/console/v1/v1_resolver.go | 91 ++++-- 6 files changed, 456 insertions(+), 47 deletions(-) diff --git a/pkg/probo/document_service.go b/pkg/probo/document_service.go index de6e8c8ee..435d916fd 100644 --- a/pkg/probo/document_service.go +++ b/pkg/probo/document_service.go @@ -48,6 +48,12 @@ type ( Signatory gid.GID } + BulkRequestSignaturesRequest struct { + DocumentIDs []gid.GID + SignatoryIDs []gid.GID + RequestedBy gid.GID + } + SigningRequestData struct { OrganizationID gid.GID `json:"organization_id"` PeopleID gid.GID `json:"people_id"` @@ -550,12 +556,87 @@ func (s *DocumentService) GetVersionSignature( return documentVersionSignature, nil } +func (s *DocumentService) BulkRequestSignatures( + ctx context.Context, + req BulkRequestSignaturesRequest, +) ([]*coredata.DocumentVersionSignature, error) { + var signatures []*coredata.DocumentVersionSignature + + err := s.svc.pg.WithTx( + ctx, + func(tx pg.Conn) error { + for _, documentID := range req.DocumentIDs { + documentVersion := &coredata.DocumentVersion{} + if err := documentVersion.LoadLatestVersion(ctx, tx, s.svc.scope, documentID); err != nil { + return fmt.Errorf("cannot load latest version for document %q: %w", documentID, err) + } + + if documentVersion.Status != coredata.DocumentStatusPublished { + return fmt.Errorf("cannot request signature for unpublished document %q", documentID) + } + + requestedBy := &coredata.People{} + if err := requestedBy.LoadByID(ctx, tx, s.svc.scope, req.RequestedBy); err != nil { + return fmt.Errorf("cannot load requested by: %w", err) + } + + for _, signatoryID := range req.SignatoryIDs { + signature, err := s.createSignatureRequestInTx(ctx, tx, documentVersion.ID, requestedBy, signatoryID) + if err != nil { + return fmt.Errorf("cannot create signature request for document %q and signatory %q: %w", documentID, signatoryID, err) + } + signatures = append(signatures, signature) + } + } + return nil + }, + ) + + if err != nil { + return nil, err + } + + return signatures, nil +} + +func (s *DocumentService) createSignatureRequestInTx( + ctx context.Context, + tx pg.Conn, + documentVersionID gid.GID, + requestedBy *coredata.People, + signatoryID gid.GID, +) (*coredata.DocumentVersionSignature, error) { + documentVersionSignatureID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionSignatureEntityType) + signatory := &coredata.People{} + + if err := signatory.LoadByID(ctx, tx, s.svc.scope, signatoryID); err != nil { + return nil, fmt.Errorf("cannot load signatory: %w", err) + } + + now := time.Now() + documentVersionSignature := &coredata.DocumentVersionSignature{ + ID: documentVersionSignatureID, + DocumentVersionID: documentVersionID, + State: coredata.DocumentVersionSignatureStateRequested, + RequestedBy: requestedBy.ID, + RequestedAt: now, + SignedBy: signatory.ID, + SignedAt: nil, + CreatedAt: now, + UpdatedAt: now, + } + + if err := documentVersionSignature.Insert(ctx, tx, s.svc.scope); err != nil { + return nil, fmt.Errorf("cannot insert document version signature: %w", err) + } + + return documentVersionSignature, nil +} + func (s *DocumentService) RequestSignature( ctx context.Context, req RequestSignatureRequest, ) (*coredata.DocumentVersionSignature, error) { - documentVersionSignatureID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionSignatureEntityType) - documentVersion, err := s.GetVersion(ctx, req.DocumentVersionID) if err != nil { return nil, fmt.Errorf("cannot get document version: %w", err) @@ -565,24 +646,18 @@ func (s *DocumentService) RequestSignature( return nil, fmt.Errorf("cannot request signature for unpublished version") } - now := time.Now() - documentVersionSignature := &coredata.DocumentVersionSignature{ - ID: documentVersionSignatureID, - DocumentVersionID: req.DocumentVersionID, - State: coredata.DocumentVersionSignatureStateRequested, - RequestedBy: req.RequestedBy, - RequestedAt: now, - SignedBy: req.Signatory, - SignedAt: nil, - CreatedAt: now, - UpdatedAt: now, - } - + var signature *coredata.DocumentVersionSignature err = s.svc.pg.WithTx( ctx, - func(conn pg.Conn) error { - if err := documentVersionSignature.Insert(ctx, conn, s.svc.scope); err != nil { - return fmt.Errorf("cannot insert document version signature: %w", err) + func(tx pg.Conn) error { + requestedBy := &coredata.People{} + if err := requestedBy.LoadByID(ctx, tx, s.svc.scope, req.RequestedBy); err != nil { + return fmt.Errorf("cannot load requested by %q: %w", req.RequestedBy, err) + } + + signature, err = s.createSignatureRequestInTx(ctx, tx, req.DocumentVersionID, requestedBy, req.Signatory) + if err != nil { + return fmt.Errorf("cannot create signature request: %w", err) } return nil @@ -593,7 +668,7 @@ func (s *DocumentService) RequestSignature( return nil, err } - return documentVersionSignature, nil + return signature, nil } func (s *DocumentService) ListSignatures( diff --git a/pkg/server/api/console/v1/schema.graphql b/pkg/server/api/console/v1/schema.graphql index 848d2269d..a8d0e3bc7 100644 --- a/pkg/server/api/console/v1/schema.graphql +++ b/pkg/server/api/console/v1/schema.graphql @@ -1397,6 +1397,9 @@ type Mutation { input: UpdateDocumentVersionInput! ): UpdateDocumentVersionPayload! requestSignature(input: RequestSignatureInput!): RequestSignaturePayload! + bulkRequestSignatures( + input: BulkRequestSignaturesInput! + ): BulkRequestSignaturesPayload! sendSigningNotifications( input: SendSigningNotificationsInput! ): SendSigningNotificationsPayload! @@ -2098,10 +2101,19 @@ input RequestSignatureInput { signatoryId: ID! } +input BulkRequestSignaturesInput { + documentIds: [ID!]! + signatoryIds: [ID!]! +} + type RequestSignaturePayload { documentVersionSignatureEdge: DocumentVersionSignatureEdge! } +type BulkRequestSignaturesPayload { + documentVersionSignatureEdges: [DocumentVersionSignatureEdge!]! +} + input BulkPublishDocumentVersionsInput { documentIds: [ID!]! changelog: String! diff --git a/pkg/server/api/console/v1/schema/schema.go b/pkg/server/api/console/v1/schema/schema.go index 368d4b763..c97b096a6 100644 --- a/pkg/server/api/console/v1/schema/schema.go +++ b/pkg/server/api/console/v1/schema/schema.go @@ -116,6 +116,10 @@ type ComplexityRoot struct { DocumentVersionEdges func(childComplexity int) int } + BulkRequestSignaturesPayload struct { + DocumentVersionSignatureEdges func(childComplexity int) int + } + CancelSignatureRequestPayload struct { DeletedDocumentVersionSignatureID func(childComplexity int) int } @@ -514,6 +518,7 @@ type ComplexityRoot struct { AssessVendor func(childComplexity int, input types.AssessVendorInput) int AssignTask func(childComplexity int, input types.AssignTaskInput) int BulkPublishDocumentVersions func(childComplexity int, input types.BulkPublishDocumentVersionsInput) int + BulkRequestSignatures func(childComplexity int, input types.BulkRequestSignaturesInput) int CancelSignatureRequest func(childComplexity int, input types.CancelSignatureRequestInput) int ConfirmEmail func(childComplexity int, input types.ConfirmEmailInput) int CreateAsset func(childComplexity int, input types.CreateAssetInput) int @@ -1035,6 +1040,7 @@ type MutationResolver interface { CreateDraftDocumentVersion(ctx context.Context, input types.CreateDraftDocumentVersionInput) (*types.CreateDraftDocumentVersionPayload, error) UpdateDocumentVersion(ctx context.Context, input types.UpdateDocumentVersionInput) (*types.UpdateDocumentVersionPayload, error) RequestSignature(ctx context.Context, input types.RequestSignatureInput) (*types.RequestSignaturePayload, error) + BulkRequestSignatures(ctx context.Context, input types.BulkRequestSignaturesInput) (*types.BulkRequestSignaturesPayload, error) SendSigningNotifications(ctx context.Context, input types.SendSigningNotificationsInput) (*types.SendSigningNotificationsPayload, error) CancelSignatureRequest(ctx context.Context, input types.CancelSignatureRequestInput) (*types.CancelSignatureRequestPayload, error) ExportDocumentVersionPDF(ctx context.Context, input types.ExportDocumentVersionPDFInput) (*types.ExportDocumentVersionPDFPayload, error) @@ -1280,6 +1286,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.BulkPublishDocumentVersionsPayload.DocumentVersionEdges(childComplexity), true + case "BulkRequestSignaturesPayload.documentVersionSignatureEdges": + if e.complexity.BulkRequestSignaturesPayload.DocumentVersionSignatureEdges == nil { + break + } + + return e.complexity.BulkRequestSignaturesPayload.DocumentVersionSignatureEdges(childComplexity), true + case "CancelSignatureRequestPayload.deletedDocumentVersionSignatureId": if e.complexity.CancelSignatureRequestPayload.DeletedDocumentVersionSignatureID == nil { break @@ -2638,6 +2651,18 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.Mutation.BulkPublishDocumentVersions(childComplexity, args["input"].(types.BulkPublishDocumentVersionsInput)), true + case "Mutation.bulkRequestSignatures": + if e.complexity.Mutation.BulkRequestSignatures == nil { + break + } + + args, err := ec.field_Mutation_bulkRequestSignatures_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.BulkRequestSignatures(childComplexity, args["input"].(types.BulkRequestSignaturesInput)), true + case "Mutation.cancelSignatureRequest": if e.complexity.Mutation.CancelSignatureRequest == nil { break @@ -4755,6 +4780,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputAssetOrder, ec.unmarshalInputAssignTaskInput, ec.unmarshalInputBulkPublishDocumentVersionsInput, + ec.unmarshalInputBulkRequestSignaturesInput, ec.unmarshalInputCancelSignatureRequestInput, ec.unmarshalInputConfirmEmailInput, ec.unmarshalInputConnectorOrder, @@ -6338,6 +6364,9 @@ type Mutation { input: UpdateDocumentVersionInput! ): UpdateDocumentVersionPayload! requestSignature(input: RequestSignatureInput!): RequestSignaturePayload! + bulkRequestSignatures( + input: BulkRequestSignaturesInput! + ): BulkRequestSignaturesPayload! sendSigningNotifications( input: SendSigningNotificationsInput! ): SendSigningNotificationsPayload! @@ -7039,10 +7068,19 @@ input RequestSignatureInput { signatoryId: ID! } +input BulkRequestSignaturesInput { + documentIds: [ID!]! + signatoryIds: [ID!]! +} + type RequestSignaturePayload { documentVersionSignatureEdge: DocumentVersionSignatureEdge! } +type BulkRequestSignaturesPayload { + documentVersionSignatureEdges: [DocumentVersionSignatureEdge!]! +} + input BulkPublishDocumentVersionsInput { documentIds: [ID!]! changelog: String! @@ -8618,6 +8656,29 @@ func (ec *executionContext) field_Mutation_bulkPublishDocumentVersions_argsInput return zeroVal, nil } +func (ec *executionContext) field_Mutation_bulkRequestSignatures_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Mutation_bulkRequestSignatures_argsInput(ctx, rawArgs) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} +func (ec *executionContext) field_Mutation_bulkRequestSignatures_argsInput( + ctx context.Context, + rawArgs map[string]any, +) (types.BulkRequestSignaturesInput, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + if tmp, ok := rawArgs["input"]; ok { + return ec.unmarshalNBulkRequestSignaturesInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐBulkRequestSignaturesInput(ctx, tmp) + } + + var zeroVal types.BulkRequestSignaturesInput + return zeroVal, nil +} + func (ec *executionContext) field_Mutation_cancelSignatureRequest_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -13275,6 +13336,56 @@ func (ec *executionContext) fieldContext_BulkPublishDocumentVersionsPayload_docu return fc, nil } +func (ec *executionContext) _BulkRequestSignaturesPayload_documentVersionSignatureEdges(ctx context.Context, field graphql.CollectedField, obj *types.BulkRequestSignaturesPayload) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_BulkRequestSignaturesPayload_documentVersionSignatureEdges(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.DocumentVersionSignatureEdges, 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.DocumentVersionSignatureEdge) + fc.Result = res + return ec.marshalNDocumentVersionSignatureEdge2ᚕᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDocumentVersionSignatureEdgeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_BulkRequestSignaturesPayload_documentVersionSignatureEdges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "BulkRequestSignaturesPayload", + 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_DocumentVersionSignatureEdge_cursor(ctx, field) + case "node": + return ec.fieldContext_DocumentVersionSignatureEdge_node(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type DocumentVersionSignatureEdge", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _CancelSignatureRequestPayload_deletedDocumentVersionSignatureId(ctx context.Context, field graphql.CollectedField, obj *types.CancelSignatureRequestPayload) (ret graphql.Marshaler) { fc, err := ec.fieldContext_CancelSignatureRequestPayload_deletedDocumentVersionSignatureId(ctx, field) if err != nil { @@ -25538,6 +25649,65 @@ func (ec *executionContext) fieldContext_Mutation_requestSignature(ctx context.C return fc, nil } +func (ec *executionContext) _Mutation_bulkRequestSignatures(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_bulkRequestSignatures(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().BulkRequestSignatures(rctx, fc.Args["input"].(types.BulkRequestSignaturesInput)) + }) + 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.BulkRequestSignaturesPayload) + fc.Result = res + return ec.marshalNBulkRequestSignaturesPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐBulkRequestSignaturesPayload(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_bulkRequestSignatures(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 "documentVersionSignatureEdges": + return ec.fieldContext_BulkRequestSignaturesPayload_documentVersionSignatureEdges(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type BulkRequestSignaturesPayload", 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_bulkRequestSignatures_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _Mutation_sendSigningNotifications(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Mutation_sendSigningNotifications(ctx, field) if err != nil { @@ -37674,6 +37844,40 @@ func (ec *executionContext) unmarshalInputBulkPublishDocumentVersionsInput(ctx c return it, nil } +func (ec *executionContext) unmarshalInputBulkRequestSignaturesInput(ctx context.Context, obj any) (types.BulkRequestSignaturesInput, error) { + var it types.BulkRequestSignaturesInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"documentIds", "signatoryIds"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "documentIds": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("documentIds")) + data, err := ec.unmarshalNID2ᚕgithubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGIDᚄ(ctx, v) + if err != nil { + return it, err + } + it.DocumentIds = data + case "signatoryIds": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("signatoryIds")) + data, err := ec.unmarshalNID2ᚕgithubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGIDᚄ(ctx, v) + if err != nil { + return it, err + } + it.SignatoryIds = data + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputCancelSignatureRequestInput(ctx context.Context, obj any) (types.CancelSignatureRequestInput, error) { var it types.CancelSignatureRequestInput asMap := map[string]any{} @@ -41931,6 +42135,45 @@ func (ec *executionContext) _BulkPublishDocumentVersionsPayload(ctx context.Cont return out } +var bulkRequestSignaturesPayloadImplementors = []string{"BulkRequestSignaturesPayload"} + +func (ec *executionContext) _BulkRequestSignaturesPayload(ctx context.Context, sel ast.SelectionSet, obj *types.BulkRequestSignaturesPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, bulkRequestSignaturesPayloadImplementors) + + 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("BulkRequestSignaturesPayload") + case "documentVersionSignatureEdges": + out.Values[i] = ec._BulkRequestSignaturesPayload_documentVersionSignatureEdges(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 cancelSignatureRequestPayloadImplementors = []string{"CancelSignatureRequestPayload"} func (ec *executionContext) _CancelSignatureRequestPayload(ctx context.Context, sel ast.SelectionSet, obj *types.CancelSignatureRequestPayload) graphql.Marshaler { @@ -46625,6 +46868,13 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) if out.Values[i] == graphql.Null { out.Invalids++ } + case "bulkRequestSignatures": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_bulkRequestSignatures(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } case "sendSigningNotifications": out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { return ec._Mutation_sendSigningNotifications(ctx, field) @@ -50932,6 +51182,25 @@ func (ec *executionContext) marshalNBulkPublishDocumentVersionsPayload2ᚖgithub return ec._BulkPublishDocumentVersionsPayload(ctx, sel, v) } +func (ec *executionContext) unmarshalNBulkRequestSignaturesInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐBulkRequestSignaturesInput(ctx context.Context, v any) (types.BulkRequestSignaturesInput, error) { + res, err := ec.unmarshalInputBulkRequestSignaturesInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNBulkRequestSignaturesPayload2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐBulkRequestSignaturesPayload(ctx context.Context, sel ast.SelectionSet, v types.BulkRequestSignaturesPayload) graphql.Marshaler { + return ec._BulkRequestSignaturesPayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNBulkRequestSignaturesPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐBulkRequestSignaturesPayload(ctx context.Context, sel ast.SelectionSet, v *types.BulkRequestSignaturesPayload) 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._BulkRequestSignaturesPayload(ctx, sel, v) +} + func (ec *executionContext) unmarshalNBusinessImpact2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐBusinessImpact(ctx context.Context, v any) (coredata.BusinessImpact, error) { tmp, err := graphql.UnmarshalString(v) res := unmarshalNBusinessImpact2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐBusinessImpact[tmp] diff --git a/pkg/server/api/console/v1/types/document_version_signature.go b/pkg/server/api/console/v1/types/document_version_signature.go index 9ba141617..ce7533056 100644 --- a/pkg/server/api/console/v1/types/document_version_signature.go +++ b/pkg/server/api/console/v1/types/document_version_signature.go @@ -35,6 +35,15 @@ func NewDocumentVersionSignatureConnection(page *page.Page[*coredata.DocumentVer } } +func NewDocumentVersionSignatureEdges(documentVersionSignatures []*coredata.DocumentVersionSignature, orderBy coredata.DocumentVersionSignatureOrderField) []*DocumentVersionSignatureEdge { + edges := make([]*DocumentVersionSignatureEdge, len(documentVersionSignatures)) + for i := range edges { + edges[i] = NewDocumentVersionSignatureEdge(documentVersionSignatures[i], orderBy) + } + + return edges +} + func NewDocumentVersionSignatureEdge(documentVersionSignature *coredata.DocumentVersionSignature, orderBy coredata.DocumentVersionSignatureOrderField) *DocumentVersionSignatureEdge { return &DocumentVersionSignatureEdge{ Cursor: documentVersionSignature.CursorKey(orderBy), diff --git a/pkg/server/api/console/v1/types/types.go b/pkg/server/api/console/v1/types/types.go index 30a7d2666..95cd11f64 100644 --- a/pkg/server/api/console/v1/types/types.go +++ b/pkg/server/api/console/v1/types/types.go @@ -66,6 +66,15 @@ type BulkPublishDocumentVersionsPayload struct { DocumentEdges []*DocumentEdge `json:"documentEdges"` } +type BulkRequestSignaturesInput struct { + DocumentIds []gid.GID `json:"documentIds"` + SignatoryIds []gid.GID `json:"signatoryIds"` +} + +type BulkRequestSignaturesPayload struct { + DocumentVersionSignatureEdges []*DocumentVersionSignatureEdge `json:"documentVersionSignatureEdges"` +} + type CancelSignatureRequestInput struct { DocumentVersionSignatureID gid.GID `json:"documentVersionSignatureId"` } diff --git a/pkg/server/api/console/v1/v1_resolver.go b/pkg/server/api/console/v1/v1_resolver.go index 8d77519a5..5d48102cf 100644 --- a/pkg/server/api/console/v1/v1_resolver.go +++ b/pkg/server/api/console/v1/v1_resolver.go @@ -1836,6 +1836,35 @@ func (r *mutationResolver) PublishDocumentVersion(ctx context.Context, input typ }, nil } +// BulkPublishDocumentVersions is the resolver for the bulkPublishDocumentVersions field. +func (r *mutationResolver) BulkPublishDocumentVersions(ctx context.Context, input types.BulkPublishDocumentVersionsInput) (*types.BulkPublishDocumentVersionsPayload, error) { + if len(input.DocumentIds) == 0 { + return &types.BulkPublishDocumentVersionsPayload{ + DocumentVersionEdges: []*types.DocumentVersionEdge{}, + DocumentEdges: []*types.DocumentEdge{}, + }, nil + } + + prb := r.ProboService(ctx, input.DocumentIds[0].TenantID()) + + user := UserFromContext(ctx) + + people, err := prb.Peoples.GetByUserID(ctx, user.ID) + if err != nil { + panic(fmt.Errorf("cannot get people: %w", err)) + } + + documentVersions, documents, err := prb.Documents.BulkPublishVersions(ctx, input.DocumentIds, people.ID, input.Changelog) + if err != nil { + panic(fmt.Errorf("cannot bulk publish document versions: %w", err)) + } + + return &types.BulkPublishDocumentVersionsPayload{ + DocumentVersionEdges: types.NewDocumentVersionEdges(documentVersions, coredata.DocumentVersionOrderFieldCreatedAt), + DocumentEdges: types.NewDocumentEdges(documents, coredata.DocumentOrderFieldTitle), + }, nil +} + // GenerateDocumentChangelog is the resolver for the generateDocumentChangelog field. func (r *mutationResolver) GenerateDocumentChangelog(ctx context.Context, input types.GenerateDocumentChangelogInput) (*types.GenerateDocumentChangelogPayload, error) { prb := r.ProboService(ctx, input.DocumentID.TenantID()) @@ -1915,6 +1944,40 @@ func (r *mutationResolver) RequestSignature(ctx context.Context, input types.Req }, nil } +// BulkRequestSignatures is the resolver for the bulkRequestSignatures field. +func (r *mutationResolver) BulkRequestSignatures(ctx context.Context, input types.BulkRequestSignaturesInput) (*types.BulkRequestSignaturesPayload, error) { + if len(input.DocumentIds) == 0 { + return &types.BulkRequestSignaturesPayload{ + DocumentVersionSignatureEdges: []*types.DocumentVersionSignatureEdge{}, + }, nil + } + + prb := r.ProboService(ctx, input.DocumentIds[0].TenantID()) + + user := UserFromContext(ctx) + + people, err := prb.Peoples.GetByUserID(ctx, user.ID) + if err != nil { + panic(fmt.Errorf("cannot get people: %w", err)) + } + + documentVersionSignatures, err := prb.Documents.BulkRequestSignatures( + ctx, + probo.BulkRequestSignaturesRequest{ + DocumentIDs: input.DocumentIds, + SignatoryIDs: input.SignatoryIds, + RequestedBy: people.ID, + }, + ) + if err != nil { + panic(fmt.Errorf("cannot bulk request signatures: %w", err)) + } + + return &types.BulkRequestSignaturesPayload{ + DocumentVersionSignatureEdges: types.NewDocumentVersionSignatureEdges(documentVersionSignatures, coredata.DocumentVersionSignatureOrderFieldCreatedAt), + }, nil +} + // SendSigningNotifications is the resolver for the sendSigningNotifications field. func (r *mutationResolver) SendSigningNotifications(ctx context.Context, input types.SendSigningNotificationsInput) (*types.SendSigningNotificationsPayload, error) { prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -1957,34 +2020,6 @@ func (r *mutationResolver) ExportDocumentVersionPDF(ctx context.Context, input t }, nil } -func (r *mutationResolver) BulkPublishDocumentVersions(ctx context.Context, input types.BulkPublishDocumentVersionsInput) (*types.BulkPublishDocumentVersionsPayload, error) { - if len(input.DocumentIds) == 0 { - return &types.BulkPublishDocumentVersionsPayload{ - DocumentVersionEdges: []*types.DocumentVersionEdge{}, - DocumentEdges: []*types.DocumentEdge{}, - }, nil - } - - prb := r.ProboService(ctx, input.DocumentIds[0].TenantID()) - - user := UserFromContext(ctx) - - people, err := prb.Peoples.GetByUserID(ctx, user.ID) - if err != nil { - panic(fmt.Errorf("cannot get people: %w", err)) - } - - documentVersions, documents, err := prb.Documents.BulkPublishVersions(ctx, input.DocumentIds, people.ID, input.Changelog) - if err != nil { - panic(fmt.Errorf("cannot bulk publish document versions: %w", err)) - } - - return &types.BulkPublishDocumentVersionsPayload{ - DocumentVersionEdges: types.NewDocumentVersionEdges(documentVersions, coredata.DocumentVersionOrderFieldCreatedAt), - DocumentEdges: types.NewDocumentEdges(documents, coredata.DocumentOrderFieldTitle), - }, nil -} - // CreateVendorRiskAssessment is the resolver for the createVendorRiskAssessment field. func (r *mutationResolver) CreateVendorRiskAssessment(ctx context.Context, input types.CreateVendorRiskAssessmentInput) (*types.CreateVendorRiskAssessmentPayload, error) { prb := r.ProboService(ctx, input.VendorID.TenantID())