From d9f78fae125ab4324e93db2d27687da8e8b39e73 Mon Sep 17 00:00:00 2001 From: Bryan Frimin Date: Mon, 7 Jul 2025 16:15:17 +0200 Subject: [PATCH] Add cancel request signature mutation Signed-off-by: Bryan Frimin --- pkg/coredata/document_version_signature.go | 26 +++ pkg/probo/document_service.go | 18 ++ pkg/server/api/console/v1/schema.graphql | 11 + pkg/server/api/console/v1/schema/schema.go | 255 +++++++++++++++++++++ pkg/server/api/console/v1/types/types.go | 8 + pkg/server/api/console/v1/v1_resolver.go | 16 +- 6 files changed, 333 insertions(+), 1 deletion(-) diff --git a/pkg/coredata/document_version_signature.go b/pkg/coredata/document_version_signature.go index 8e185d79a..49acfcded 100644 --- a/pkg/coredata/document_version_signature.go +++ b/pkg/coredata/document_version_signature.go @@ -279,3 +279,29 @@ WHERE return nil } + +func (pvs *DocumentVersionSignature) Delete( + ctx context.Context, + conn pg.Conn, + scope Scoper, + documentVersionSignatureID gid.GID, +) error { + q := ` +DELETE FROM document_version_signatures +WHERE + %s + AND id = @id +` + + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.StrictNamedArgs{"id": documentVersionSignatureID} + maps.Copy(args, scope.SQLArguments()) + + _, err := conn.Exec(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot delete document version signature: %w", err) + } + + return nil +} diff --git a/pkg/probo/document_service.go b/pkg/probo/document_service.go index 111bb1fda..feda56ccf 100644 --- a/pkg/probo/document_service.go +++ b/pkg/probo/document_service.go @@ -864,6 +864,24 @@ func (s *DocumentService) Update( return document, nil } +func (s *DocumentService) CancelSignatureRequest( + ctx context.Context, + documentVersionSignatureID gid.GID, +) error { + documentVersionSignature := &coredata.DocumentVersionSignature{} + + return s.svc.pg.WithTx( + ctx, + func(tx pg.Conn) error { + if err := documentVersionSignature.Delete(ctx, tx, s.svc.scope, documentVersionSignatureID); err != nil { + return fmt.Errorf("cannot delete document version signature: %w", err) + } + + return nil + }, + ) +} + func (s *DocumentService) ExportPDF( ctx context.Context, documentVersionID gid.GID, diff --git a/pkg/server/api/console/v1/schema.graphql b/pkg/server/api/console/v1/schema.graphql index d8a894ab2..76b9cbd93 100644 --- a/pkg/server/api/console/v1/schema.graphql +++ b/pkg/server/api/console/v1/schema.graphql @@ -1397,6 +1397,9 @@ type Mutation { sendSigningNotifications( input: SendSigningNotificationsInput! ): SendSigningNotificationsPayload! + cancelSignatureRequest( + input: CancelSignatureRequestInput! + ): CancelSignatureRequestPayload! exportDocumentVersionPDF( input: ExportDocumentVersionPDFInput! ): ExportDocumentVersionPDFPayload! @@ -2119,6 +2122,10 @@ input UpdateDocumentVersionInput { content: String! } +input CancelSignatureRequestInput { + documentVersionSignatureId: ID! +} + type UpdateDocumentVersionPayload { documentVersion: DocumentVersion! } @@ -2131,6 +2138,10 @@ type SendSigningNotificationsPayload { success: Boolean! } +type CancelSignatureRequestPayload { + deletedDocumentVersionSignatureId: ID! +} + type UploadTaskEvidencePayload { evidenceEdge: EvidenceEdge! } diff --git a/pkg/server/api/console/v1/schema/schema.go b/pkg/server/api/console/v1/schema/schema.go index d1e39c97b..172acdf92 100644 --- a/pkg/server/api/console/v1/schema/schema.go +++ b/pkg/server/api/console/v1/schema/schema.go @@ -111,6 +111,10 @@ type ComplexityRoot struct { Task func(childComplexity int) int } + CancelSignatureRequestPayload struct { + DeletedDocumentVersionSignatureID func(childComplexity int) int + } + ConfirmEmailPayload struct { Success func(childComplexity int) int } @@ -504,6 +508,7 @@ type ComplexityRoot struct { Mutation struct { AssessVendor func(childComplexity int, input types.AssessVendorInput) int AssignTask func(childComplexity int, input types.AssignTaskInput) 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 CreateControl func(childComplexity int, input types.CreateControlInput) int @@ -1024,6 +1029,7 @@ type MutationResolver interface { UpdateDocumentVersion(ctx context.Context, input types.UpdateDocumentVersionInput) (*types.UpdateDocumentVersionPayload, error) RequestSignature(ctx context.Context, input types.RequestSignatureInput) (*types.RequestSignaturePayload, 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) CreateVendorRiskAssessment(ctx context.Context, input types.CreateVendorRiskAssessmentInput) (*types.CreateVendorRiskAssessmentPayload, error) ExportAudit(ctx context.Context, input types.ExportAuditInput) (*types.ExportAuditPayload, error) @@ -1253,6 +1259,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.AssignTaskPayload.Task(childComplexity), true + case "CancelSignatureRequestPayload.deletedDocumentVersionSignatureId": + if e.complexity.CancelSignatureRequestPayload.DeletedDocumentVersionSignatureID == nil { + break + } + + return e.complexity.CancelSignatureRequestPayload.DeletedDocumentVersionSignatureID(childComplexity), true + case "ConfirmEmailPayload.success": if e.complexity.ConfirmEmailPayload.Success == nil { break @@ -2592,6 +2605,18 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.Mutation.AssignTask(childComplexity, args["input"].(types.AssignTaskInput)), true + case "Mutation.cancelSignatureRequest": + if e.complexity.Mutation.CancelSignatureRequest == nil { + break + } + + args, err := ec.field_Mutation_cancelSignatureRequest_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.CancelSignatureRequest(childComplexity, args["input"].(types.CancelSignatureRequestInput)), true + case "Mutation.confirmEmail": if e.complexity.Mutation.ConfirmEmail == nil { break @@ -4696,6 +4721,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputAssessVendorInput, ec.unmarshalInputAssetOrder, ec.unmarshalInputAssignTaskInput, + ec.unmarshalInputCancelSignatureRequestInput, ec.unmarshalInputConfirmEmailInput, ec.unmarshalInputConnectorOrder, ec.unmarshalInputControlFilter, @@ -6278,6 +6304,9 @@ type Mutation { sendSigningNotifications( input: SendSigningNotificationsInput! ): SendSigningNotificationsPayload! + cancelSignatureRequest( + input: CancelSignatureRequestInput! + ): CancelSignatureRequestPayload! exportDocumentVersionPDF( input: ExportDocumentVersionPDFInput! ): ExportDocumentVersionPDFPayload! @@ -7000,6 +7029,10 @@ input UpdateDocumentVersionInput { content: String! } +input CancelSignatureRequestInput { + documentVersionSignatureId: ID! +} + type UpdateDocumentVersionPayload { documentVersion: DocumentVersion! } @@ -7012,6 +7045,10 @@ type SendSigningNotificationsPayload { success: Boolean! } +type CancelSignatureRequestPayload { + deletedDocumentVersionSignatureId: ID! +} + type UploadTaskEvidencePayload { evidenceEdge: EvidenceEdge! } @@ -8511,6 +8548,29 @@ func (ec *executionContext) field_Mutation_assignTask_argsInput( 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{} + arg0, err := ec.field_Mutation_cancelSignatureRequest_argsInput(ctx, rawArgs) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} +func (ec *executionContext) field_Mutation_cancelSignatureRequest_argsInput( + ctx context.Context, + rawArgs map[string]any, +) (types.CancelSignatureRequestInput, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + if tmp, ok := rawArgs["input"]; ok { + return ec.unmarshalNCancelSignatureRequestInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCancelSignatureRequestInput(ctx, tmp) + } + + var zeroVal types.CancelSignatureRequestInput + return zeroVal, nil +} + func (ec *executionContext) field_Mutation_confirmEmail_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -13045,6 +13105,50 @@ func (ec *executionContext) fieldContext_AssignTaskPayload_task(_ context.Contex 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 { + 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.DeletedDocumentVersionSignatureID, 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_CancelSignatureRequestPayload_deletedDocumentVersionSignatureId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CancelSignatureRequestPayload", + 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) _ConfirmEmailPayload_success(ctx context.Context, field graphql.CollectedField, obj *types.ConfirmEmailPayload) (ret graphql.Marshaler) { fc, err := ec.fieldContext_ConfirmEmailPayload_success(ctx, field) if err != nil { @@ -25262,6 +25366,65 @@ func (ec *executionContext) fieldContext_Mutation_sendSigningNotifications(ctx c return fc, nil } +func (ec *executionContext) _Mutation_cancelSignatureRequest(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_cancelSignatureRequest(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().CancelSignatureRequest(rctx, fc.Args["input"].(types.CancelSignatureRequestInput)) + }) + 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.CancelSignatureRequestPayload) + fc.Result = res + return ec.marshalNCancelSignatureRequestPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCancelSignatureRequestPayload(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_cancelSignatureRequest(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 "deletedDocumentVersionSignatureId": + return ec.fieldContext_CancelSignatureRequestPayload_deletedDocumentVersionSignatureId(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type CancelSignatureRequestPayload", 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_cancelSignatureRequest_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _Mutation_exportDocumentVersionPDF(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Mutation_exportDocumentVersionPDF(ctx, field) if err != nil { @@ -37246,6 +37409,33 @@ func (ec *executionContext) unmarshalInputAssignTaskInput(ctx context.Context, o return it, nil } +func (ec *executionContext) unmarshalInputCancelSignatureRequestInput(ctx context.Context, obj any) (types.CancelSignatureRequestInput, error) { + var it types.CancelSignatureRequestInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"documentVersionSignatureId"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "documentVersionSignatureId": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("documentVersionSignatureId")) + data, err := ec.unmarshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v) + if err != nil { + return it, err + } + it.DocumentVersionSignatureID = data + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputConfirmEmailInput(ctx context.Context, obj any) (types.ConfirmEmailInput, error) { var it types.ConfirmEmailInput asMap := map[string]any{} @@ -41432,6 +41622,45 @@ func (ec *executionContext) _AssignTaskPayload(ctx context.Context, sel ast.Sele return out } +var cancelSignatureRequestPayloadImplementors = []string{"CancelSignatureRequestPayload"} + +func (ec *executionContext) _CancelSignatureRequestPayload(ctx context.Context, sel ast.SelectionSet, obj *types.CancelSignatureRequestPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, cancelSignatureRequestPayloadImplementors) + + 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("CancelSignatureRequestPayload") + case "deletedDocumentVersionSignatureId": + out.Values[i] = ec._CancelSignatureRequestPayload_deletedDocumentVersionSignatureId(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 confirmEmailPayloadImplementors = []string{"ConfirmEmailPayload"} func (ec *executionContext) _ConfirmEmailPayload(ctx context.Context, sel ast.SelectionSet, obj *types.ConfirmEmailPayload) graphql.Marshaler { @@ -46087,6 +46316,13 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) if out.Values[i] == graphql.Null { out.Invalids++ } + case "cancelSignatureRequest": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_cancelSignatureRequest(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } case "exportDocumentVersionPDF": out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { return ec._Mutation_exportDocumentVersionPDF(ctx, field) @@ -50393,6 +50629,25 @@ var ( } ) +func (ec *executionContext) unmarshalNCancelSignatureRequestInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCancelSignatureRequestInput(ctx context.Context, v any) (types.CancelSignatureRequestInput, error) { + res, err := ec.unmarshalInputCancelSignatureRequestInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNCancelSignatureRequestPayload2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCancelSignatureRequestPayload(ctx context.Context, sel ast.SelectionSet, v types.CancelSignatureRequestPayload) graphql.Marshaler { + return ec._CancelSignatureRequestPayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNCancelSignatureRequestPayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCancelSignatureRequestPayload(ctx context.Context, sel ast.SelectionSet, v *types.CancelSignatureRequestPayload) 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._CancelSignatureRequestPayload(ctx, sel, v) +} + func (ec *executionContext) unmarshalNConfirmEmailInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐConfirmEmailInput(ctx context.Context, v any) (types.ConfirmEmailInput, error) { res, err := ec.unmarshalInputConfirmEmailInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) diff --git a/pkg/server/api/console/v1/types/types.go b/pkg/server/api/console/v1/types/types.go index 5135ed5f6..517a9e1a5 100644 --- a/pkg/server/api/console/v1/types/types.go +++ b/pkg/server/api/console/v1/types/types.go @@ -56,6 +56,14 @@ type AssignTaskPayload struct { Task *Task `json:"task"` } +type CancelSignatureRequestInput struct { + DocumentVersionSignatureID gid.GID `json:"documentVersionSignatureId"` +} + +type CancelSignatureRequestPayload struct { + DeletedDocumentVersionSignatureID gid.GID `json:"deletedDocumentVersionSignatureId"` +} + type ConfirmEmailInput struct { Token string `json:"token"` } diff --git a/pkg/server/api/console/v1/v1_resolver.go b/pkg/server/api/console/v1/v1_resolver.go index 2d789f913..bb6d6ce06 100644 --- a/pkg/server/api/console/v1/v1_resolver.go +++ b/pkg/server/api/console/v1/v1_resolver.go @@ -2,7 +2,7 @@ package console_v1 // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.73 +// Code generated by github.com/99designs/gqlgen version v0.17.76 import ( "context" @@ -1929,6 +1929,20 @@ func (r *mutationResolver) SendSigningNotifications(ctx context.Context, input t }, nil } +// CancelSignatureRequest is the resolver for the cancelSignatureRequest field. +func (r *mutationResolver) CancelSignatureRequest(ctx context.Context, input types.CancelSignatureRequestInput) (*types.CancelSignatureRequestPayload, error) { + prb := r.ProboService(ctx, input.DocumentVersionSignatureID.TenantID()) + + err := prb.Documents.CancelSignatureRequest(ctx, input.DocumentVersionSignatureID) + if err != nil { + panic(fmt.Errorf("cannot cancel signature request: %w", err)) + } + + return &types.CancelSignatureRequestPayload{ + DeletedDocumentVersionSignatureID: input.DocumentVersionSignatureID, + }, nil +} + // ExportDocumentVersionPDF is the resolver for the exportDocumentVersionPDF field. func (r *mutationResolver) ExportDocumentVersionPDF(ctx context.Context, input types.ExportDocumentVersionPDFInput) (*types.ExportDocumentVersionPDFPayload, error) { prb := r.ProboService(ctx, input.DocumentVersionID.TenantID())