From 752e0097b91e9e20e0d2a44c57532a32738bd253 Mon Sep 17 00:00:00 2001 From: sauravsapkota Date: Wed, 24 Jul 2024 14:36:39 +0545 Subject: [PATCH] Convert REST API for Analysis CRUD to GraphQL mutation --- apps/analysis/mutation.py | 62 ++++++++++++++++++++++++++++++++++-- apps/analysis/serializers.py | 5 +-- schema.graphql | 60 ++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 5 deletions(-) diff --git a/apps/analysis/mutation.py b/apps/analysis/mutation.py index de5bd03c19..2d98d6d66f 100644 --- a/apps/analysis/mutation.py +++ b/apps/analysis/mutation.py @@ -4,9 +4,12 @@ generate_input_type_for_serializer, PsGrapheneMutation, PsDeleteMutation, + PsBulkGrapheneMutation, +) +from deep.permissions import ( + ProjectPermissions as PP, + IsProjectMember, ) -from deep.permissions import ProjectPermissions as PP - from .models import ( AnalysisPillar, DiscardedEntry, @@ -17,6 +20,7 @@ AnalysisReport, AnalysisReportUpload, AnalysisReportSnapshot, + Analysis, ) from .schema import ( get_analysis_pillar_qs, @@ -31,6 +35,7 @@ AnalysisReportType, AnalysisReportUploadType, AnalysisReportSnapshotType, + AnalysisType, ) from .serializers import ( AnalysisPillarGqlSerializer, @@ -42,6 +47,7 @@ AnalysisReportSerializer, AnalysisReportSnapshotSerializer, AnalysisReportUploadSerializer, + AnalysisGqlSerializer, ) @@ -84,7 +90,7 @@ ) -# Analysi Report +# Analysis Report AnalysisReportInputType = generate_input_type_for_serializer( 'AnalysisReportInputType', serializer_class=AnalysisReportSerializer, @@ -105,6 +111,11 @@ serializer_class=AnalysisReportUploadSerializer, ) +AnalysisInputType = generate_input_type_for_serializer( + 'AnalysisInputType', + serializer_class=AnalysisGqlSerializer, +) + class RequiredPermissionMixin(): permissions = [ @@ -269,6 +280,46 @@ class Arguments: result = graphene.Field(AnalysisReportUploadType) +class CreateAnalysis(RequiredPermissionMixin, PsGrapheneMutation): + class Arguments: + data = AnalysisInputType(required=True) + model = Analysis + serializer_class = AnalysisGqlSerializer + result = graphene.Field(AnalysisType) + + +class UpdateAnalysis(RequiredPermissionMixin, PsGrapheneMutation): + class Arguments: + data = AnalysisInputType(required=True) + id = graphene.ID(required=True) + model = Analysis + serializer_class = AnalysisGqlSerializer + result = graphene.Field(AnalysisType) + + +class DeleteAnalysis(RequiredPermissionMixin, PsDeleteMutation): + class Arguments: + id = graphene.ID(required=True) + model = Analysis + result = graphene.Field(AnalysisType) + + +class BulkAnalysisInputType(AnalysisInputType): + id = graphene.ID() + + +class BulkAnalysis(PsBulkGrapheneMutation): + class Arguments: + items = graphene.List(graphene.NonNull(BulkAnalysisInputType)) + delete_ids = graphene.List(graphene.NonNull(graphene.ID)) + + result = graphene.List(AnalysisType) + deleted_result = graphene.List(graphene.NonNull(AnalysisType)) + model = Analysis + serializer_class = AnalysisGqlSerializer + permissions = [IsProjectMember] + + class Mutation(): # Analysis Pillar analysis_pillar_update = UpdateAnalysisPillar.Field() @@ -289,3 +340,8 @@ class Mutation(): # -- Uploads analysis_report_upload_create = CreateAnalysisReportUpload.Field() analysis_report_upload_delete = DeleteAnalysisReportUpload.Field() + # Analysis + analysis_create = CreateAnalysis.Field() + analysis_update = UpdateAnalysis.Field() + analysis_delete = DeleteAnalysis.Field() + analysis_bulk = BulkAnalysis.Field() diff --git a/apps/analysis/serializers.py b/apps/analysis/serializers.py index fbc4a41654..de39bb4ec4 100644 --- a/apps/analysis/serializers.py +++ b/apps/analysis/serializers.py @@ -409,7 +409,7 @@ def validate(self, data): return data -class AnalysisGqlSerializer(UserResourceSerializer): +class AnalysisGqlSerializer(UserResourceSerializer, ProjectPropertySerializerMixin): id = IntegerIDField(required=False) analysis_pillar = AnalysisPillarGqlSerializer(many=True, source='analysispillar_set', required=False) start_date = serializers.DateField(required=False, allow_null=True) @@ -420,10 +420,10 @@ class Meta: 'id', 'title', 'team_lead', - 'project', 'start_date', 'end_date', 'cloned_from', + 'analysis_pillar', ) def validate_project(self, project): @@ -432,6 +432,7 @@ def validate_project(self, project): return project def validate(self, data): + data['project'] = self.project start_date = data.get('start_date') end_date = data.get('end_date') if start_date and start_date > end_date: diff --git a/schema.graphql b/schema.graphql index 78207cc6d7..1a15a12bf0 100644 --- a/schema.graphql +++ b/schema.graphql @@ -260,6 +260,16 @@ type AnalysisFrameworkVisibleProjectType { isPrivate: Boolean! } +input AnalysisInputType { + id: ID + title: String! + teamLead: ID! + startDate: Date + endDate: Date! + clonedFrom: ID + analysisPillar: [AnalysisPillarGqlInputType!] +} + type AnalysisListType { results: [AnalysisType!] totalCount: Int @@ -304,6 +314,18 @@ type AnalysisPillarEntryListType { pageSize: Int } +input AnalysisPillarGqlInputType { + title: String! + mainStatement: String + informationGap: String + filters: GenericScalar + assignee: ID! + analysis: ID! + clonedFrom: ID + statements: [AnalyticalStatementGqlInputType!] + clientId: String +} + type AnalysisPillarListType { results: [AnalysisPillarType!] totalCount: Int @@ -3258,6 +3280,12 @@ enum AutomaticSummaryStatusEnum { SEND_FAILED } +type BulkAnalysis { + errors: [[GenericScalar!]] + result: [AnalysisType] + deletedResult: [AnalysisType!] +} + input BulkAnalysisFrameworkMembershipInputType { id: ID member: ID! @@ -3265,6 +3293,16 @@ input BulkAnalysisFrameworkMembershipInputType { clientId: String } +input BulkAnalysisInputType { + id: ID + title: String! + teamLead: ID! + startDate: Date + endDate: Date! + clonedFrom: ID + analysisPillar: [AnalysisPillarGqlInputType!] +} + type BulkEntry { errors: [[GenericScalar!]] result: [EntryType] @@ -3535,6 +3573,12 @@ type ConnectorSourceType { statusDisplay: EnumDescription! } +type CreateAnalysis { + errors: [GenericScalar!] + ok: Boolean + result: AnalysisType +} + type CreateAnalysisFramework { errors: [GenericScalar!] ok: Boolean @@ -3660,6 +3704,12 @@ scalar DateTime scalar Decimal +type DeleteAnalysis { + errors: [GenericScalar!] + ok: Boolean + result: AnalysisType +} + type DeleteAnalysisPillarDiscardedEntry { errors: [GenericScalar!] ok: Boolean @@ -5421,6 +5471,10 @@ type ProjectMutationType { analysisReportSnapshotCreate(data: AnalysisReportSnapshotInputType!): CreateAnalysisReportSnapshot analysisReportUploadCreate(data: AnalysisReportUploadInputType!): CreateAnalysisReportUpload analysisReportUploadDelete(id: ID!): DeleteAnalysisReportUpload + analysisCreate(data: AnalysisInputType!): CreateAnalysis + analysisUpdate(data: AnalysisInputType!, id: ID!): UpdateAnalysis + analysisDelete(id: ID!): DeleteAnalysis + analysisBulk(deleteIds: [ID!], items: [BulkAnalysisInputType!]): BulkAnalysis exportCreate(data: ExportCreateInputType!): CreateUserExport exportUpdate(data: ExportUpdateInputType!, id: ID!): UpdateUserExport exportCancel(id: ID!): CancelUserExport @@ -6301,6 +6355,12 @@ input UnifiedConnectorWithSourceInputType { sources: [ConnectorSourceGqInputType!] } +type UpdateAnalysis { + errors: [GenericScalar!] + ok: Boolean + result: AnalysisType +} + type UpdateAnalysisFramework { errors: [GenericScalar!] ok: Boolean