From 08db654b86c20a7b1c4e3381bb09ab1a63f6f216 Mon Sep 17 00:00:00 2001 From: bhavanakarwade <137506897+bhavanakarwade@users.noreply.github.com> Date: Mon, 17 Jun 2024 15:00:14 +0530 Subject: [PATCH] feat: delete verification records by orgId (#779) * feat: delete verification records Signed-off-by: bhavanakarwade * fix: refactored enum Signed-off-by: bhavanakarwade --------- Signed-off-by: bhavanakarwade Signed-off-by: KulkarniShashank --- .../verification/verification.controller.ts | 10 +++-- .../src/verification/verification.service.ts | 7 ++-- .../repositories/verification.repository.ts | 2 +- .../src/verification.controller.ts | 10 ++--- apps/verification/src/verification.service.ts | 42 +++++++++++++++---- libs/enum/src/enum.ts | 12 ++++++ libs/user-activity/repositories/index.ts | 15 +------ .../src/user-activity.service.ts | 6 +-- 8 files changed, 65 insertions(+), 39 deletions(-) diff --git a/apps/api-gateway/src/verification/verification.controller.ts b/apps/api-gateway/src/verification/verification.controller.ts index 7a1387048..4b8a5c8fa 100644 --- a/apps/api-gateway/src/verification/verification.controller.ts +++ b/apps/api-gateway/src/verification/verification.controller.ts @@ -33,6 +33,8 @@ import { User } from '../authz/decorators/user.decorator'; import { GetAllProofRequestsDto } from './dto/get-all-proof-requests.dto'; import { IProofRequestSearchCriteria } from './interfaces/verification.interface'; import { ProofRequestType, SortFields } from './enum/verification.enum'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { user } from '@prisma/client'; @@ -344,20 +346,20 @@ export class VerificationController { @ApiBearerAuth() @Roles(OrgRoles.OWNER) @UseGuards(AuthGuard('jwt'), OrgRolesGuard) -async deleteOrganizationInvitation( +async deleteVerificationRecordsByOrgId( @Param( 'orgId', new ParseUUIDPipe({ exceptionFactory: (): Error => { - throw new BadRequestException(`Invalid format for orgId`); + throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId); } }) ) orgId: string, - @User() user: IUserRequest, + @User() user: user, @Res() res: Response ): Promise { - await this.verificationService.deleteVerificationRecord(orgId, user?.['id']); + await this.verificationService.deleteVerificationRecords(orgId, user); const finalResponse: IResponse = { statusCode: HttpStatus.OK, message: ResponseMessages.verification.success.deleteVerificationRecord diff --git a/apps/api-gateway/src/verification/verification.service.ts b/apps/api-gateway/src/verification/verification.service.ts index 74f15e0ac..cf9492148 100644 --- a/apps/api-gateway/src/verification/verification.service.ts +++ b/apps/api-gateway/src/verification/verification.service.ts @@ -9,6 +9,7 @@ import { IPresentation, IProofRequest, IProofRequestSearchCriteria } from './int import { IProofPresentation } from './interfaces/verification.interface'; // To do make a similar interface in API-gateway import { IRequestProof } from 'apps/verification/src/interfaces/verification.interface'; +import { user } from '@prisma/client'; @Injectable() @@ -128,8 +129,8 @@ export class VerificationService extends BaseService { } } - async deleteVerificationRecord(orgId: string, userId: string): Promise { - const payload = { orgId, userId }; - return this.sendNatsMessage(this.verificationServiceProxy, 'delete-verification-record', payload); + async deleteVerificationRecords(orgId: string, userDetails: user): Promise { + const payload = { orgId, userDetails }; + return this.sendNatsMessage(this.verificationServiceProxy, 'delete-verification-records', payload); } } diff --git a/apps/verification/src/repositories/verification.repository.ts b/apps/verification/src/repositories/verification.repository.ts index 1af69a359..1060ae05e 100644 --- a/apps/verification/src/repositories/verification.repository.ts +++ b/apps/verification/src/repositories/verification.repository.ts @@ -251,5 +251,5 @@ export class VerificationRepository { throw error; } } - + } diff --git a/apps/verification/src/verification.controller.ts b/apps/verification/src/verification.controller.ts index c40bb3c6d..e60d37983 100644 --- a/apps/verification/src/verification.controller.ts +++ b/apps/verification/src/verification.controller.ts @@ -3,7 +3,7 @@ import { VerificationService } from './verification.service'; import { MessagePattern } from '@nestjs/microservices'; import { IProofPresentation, IProofPresentationData, IProofRequests, IRequestProof, ISendProofRequestPayload } from './interfaces/verification.interface'; import { IUserRequest } from '@credebl/user-request/user-request.interface'; -import { presentations } from '@prisma/client'; +import { presentations, user } from '@prisma/client'; import { IProofPresentationDetails, IProofPresentationList, IVerificationRecords } from '@credebl/common/interfaces/verification.interface'; @Controller() @@ -79,9 +79,9 @@ export class VerificationController { return this.verificationService.getVerifiedProofdetails(proofId, orgId); } - @MessagePattern({ cmd: 'delete-verification-record' }) - async deleteVerificationRecord(payload: {orgId: string, userId: string}): Promise { - const { orgId, userId } = payload; - return this.verificationService.deleteVerificationRecord(orgId, userId); + @MessagePattern({ cmd: 'delete-verification-records' }) + async deleteVerificationRecord(payload: {orgId: string, userDetails: user}): Promise { + const { orgId, userDetails } = payload; + return this.verificationService.deleteVerificationRecords(orgId, userDetails); } } diff --git a/apps/verification/src/verification.service.ts b/apps/verification/src/verification.service.ts index 1e9fec032..995512f2e 100644 --- a/apps/verification/src/verification.service.ts +++ b/apps/verification/src/verification.service.ts @@ -5,8 +5,8 @@ import { map } from 'rxjs/operators'; import { IGetAllProofPresentations, IProofRequestSearchCriteria, IGetProofPresentationById, IProofPresentation, IProofRequestPayload, IRequestProof, ISendProofRequestPayload, IVerifyPresentation, IVerifiedProofData, IInvitation } from './interfaces/verification.interface'; import { VerificationRepository } from './repositories/verification.repository'; import { CommonConstants } from '@credebl/common/common.constant'; -import { RecordType, agent_invitations, org_agents, organisation, presentations } from '@prisma/client'; -import { AutoAccept, OrgAgentType } from '@credebl/enum/enum'; +import { RecordType, agent_invitations, org_agents, organisation, presentations, user } from '@prisma/client'; +import { AutoAccept, OrgAgentType, VerificationProcessState } from '@credebl/enum/enum'; import { ResponseMessages } from '@credebl/common/response-messages'; import * as QRCode from 'qrcode'; import { OutOfBandVerification } from '../templates/out-of-band-verification.template'; @@ -17,6 +17,7 @@ import { IProofPresentationDetails, IProofPresentationList, IVerificationRecords import { ProofRequestType } from 'apps/api-gateway/src/verification/enum/verification.enum'; import { UserActivityService } from '@credebl/user-activity'; import { convertUrlToDeepLinkUrl } from '@credebl/common/common.utils'; +import { UserActivityRepository } from 'libs/user-activity/repositories'; @Injectable() export class VerificationService { @@ -26,6 +27,7 @@ export class VerificationService { constructor( @Inject('NATS_CLIENT') private readonly verificationServiceProxy: ClientProxy, private readonly verificationRepository: VerificationRepository, + private readonly userActivityRepository: UserActivityRepository, private readonly outOfBandVerification: OutOfBandVerification, private readonly userActivityService: UserActivityService, private readonly emailData: EmailDto, @@ -940,16 +942,42 @@ export class VerificationService { return new Promise(resolve => setTimeout(resolve, ms)); } - async deleteVerificationRecord(orgId: string, userId: string): Promise { + async deleteVerificationRecords(orgId: string, userDetails: user): Promise { try { const deleteProofRecords = await this.verificationRepository.deleteVerificationRecordsByOrgId(orgId); - + + if (0 === deleteProofRecords?.deleteResult?.count) { + throw new NotFoundException(ResponseMessages.verification.error.verificationRecordsNotFound); + } + + const statusCounts = { + [VerificationProcessState.PROPOSAL_SENT]: 0, + [VerificationProcessState.PROPOSAL_RECEIVED]: 0, + [VerificationProcessState.REQUEST_SENT]: 0, + [VerificationProcessState.REQUEST_RECEIVED]: 0, + [VerificationProcessState.PRESENTATION_RECEIVED]: 0, + [VerificationProcessState.PRESENTATION_SENT]: 0, + [VerificationProcessState.DONE]: 0, + [VerificationProcessState.DECLIEND]: 0, + [VerificationProcessState.ABANDONED]: 0 + }; + + await Promise.all(deleteProofRecords.recordsToDelete.map(async (record) => { + statusCounts[record.state]++; + })); + + const filteredStatusCounts = Object.fromEntries( + Object.entries(statusCounts).filter(entry => 0 < entry[1]) + ); + const deletedVerificationData = { - deletedProofRecordsCount : deleteProofRecords?.deleteResult?.count + deletedProofRecordsCount : deleteProofRecords?.deleteResult?.count, + deletedRecordsStatusCount : filteredStatusCounts }; - await this.userActivityService.deletedRecordsDetails(userId, orgId, RecordType.VERIFICATION_RECORD, deletedVerificationData); - return deleteProofRecords; + await this.userActivityRepository._orgDeletedActivity(orgId, userDetails, deletedVerificationData, RecordType.VERIFICATION_RECORD); + + return deleteProofRecords; } catch (error) { this.logger.error(`[deleteVerificationRecords] - error in deleting verification records: ${JSON.stringify(error)}`); throw new RpcException(error.response ? error.response : error); diff --git a/libs/enum/src/enum.ts b/libs/enum/src/enum.ts index 73bcff420..5fc8a3fc4 100644 --- a/libs/enum/src/enum.ts +++ b/libs/enum/src/enum.ts @@ -145,3 +145,15 @@ export enum PromiseResult { REJECTED = 'rejected', FULFILLED = 'fulfilled' } + +export enum VerificationProcessState { + PROPOSAL_SENT = 'proposal-sent', + PROPOSAL_RECEIVED = 'proposal-received', + REQUEST_SENT = 'request-sent', + REQUEST_RECEIVED = 'request-received', + PRESENTATION_SENT = 'presentation-sent', + PRESENTATION_RECEIVED = 'presentation-received', + DECLIEND = 'declined', + ABANDONED = 'abandoned', + DONE = 'done' +} diff --git a/libs/user-activity/repositories/index.ts b/libs/user-activity/repositories/index.ts index c2a613493..7895ea825 100644 --- a/libs/user-activity/repositories/index.ts +++ b/libs/user-activity/repositories/index.ts @@ -2,7 +2,7 @@ import { HttpException, Inject, Injectable, Logger } from '@nestjs/common'; import { IUsersActivity} from '../interface'; import { PrismaService } from '@credebl/prisma-service'; -import { RecordType, user, user_activity, user_org_delete_activity } from '@prisma/client'; +import { RecordType, user, user_activity } from '@prisma/client'; import { map } from 'rxjs'; import { ClientProxy } from '@nestjs/microservices'; @@ -26,19 +26,6 @@ export class UserActivityRepository { }); } - async deletedActivity(userId: string, orgId: string, recordType: RecordType, txnMetadata:object, userEmail?: string): Promise { - return this.prisma.user_org_delete_activity.create({ - data: { - userId, - orgId, - recordType, - txnMetadata, - deletedBy: userId, - userEmail - } - }); - } - async getRecentActivities(userId: string, limit: number): Promise { return this.prisma.user_activity.findMany({ where: { diff --git a/libs/user-activity/src/user-activity.service.ts b/libs/user-activity/src/user-activity.service.ts index d17c4b0fc..f90f4f00a 100644 --- a/libs/user-activity/src/user-activity.service.ts +++ b/libs/user-activity/src/user-activity.service.ts @@ -1,7 +1,7 @@ /* eslint-disable camelcase */ import { Injectable } from '@nestjs/common'; import { UserActivityRepository } from '../repositories'; -import { RecordType, user_activity, user_org_delete_activity } from '@prisma/client'; +import { user_activity } from '@prisma/client'; import { IUsersActivity } from '../interface'; @Injectable() @@ -16,10 +16,6 @@ export class UserActivityService { return this.userActivityRepository.logActivity(userId, orgId, action, details); } - async deletedRecordsDetails(userId: string, orgId: string, recordType: RecordType, txnMetadata:object): Promise { - return this.userActivityRepository.deletedActivity(userId, orgId, recordType, txnMetadata); - } - async getUserActivity(userId: string, limit: number): Promise { return this.userActivityRepository.getRecentActivities(userId, limit); }