Skip to content

Commit

Permalink
fix: search and sorting issue in ecosystem member list API
Browse files Browse the repository at this point in the history
Signed-off-by: sanjay-k1910 <[email protected]>
Signed-off-by: bhavanakarwade <[email protected]>
  • Loading branch information
sanjay-k1910 authored and bhavanakarwade committed Feb 27, 2024
1 parent 46161b7 commit d791fbc
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 112 deletions.
16 changes: 5 additions & 11 deletions apps/api-gateway/src/authz/guards/ecosystem-roles.guard.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import { BadRequestException, CanActivate, ExecutionContext, ForbiddenException, Logger } from '@nestjs/common';

import { HttpException } from '@nestjs/common';
import { HttpStatus } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import { BadRequestException, CanActivate, ExecutionContext, ForbiddenException, Logger, Injectable } from '@nestjs/common';
import { ECOSYSTEM_ROLES_KEY } from '../decorators/roles.decorator';
import { Reflector } from '@nestjs/core';
import { EcosystemService } from '../../ecosystem/ecosystem.service';
Expand Down Expand Up @@ -54,19 +50,17 @@ export class EcosystemRolesGuard implements CanActivate {
const ecosystemOrgData = await this.ecosystemService.fetchEcosystemOrg(ecosystemId, orgId);

if (!ecosystemOrgData) {
throw new HttpException('Organization does not match', HttpStatus.FORBIDDEN);
throw new ForbiddenException('Organization does not match');
}

const {response} = ecosystemOrgData;

user.ecosystemOrgRole = response['ecosystemRole']['name'];
user.ecosystemOrgRole = ecosystemOrgData['ecosystemRole']['name'];

if (!user.ecosystemOrgRole) {
throw new HttpException('Ecosystem role not match', HttpStatus.FORBIDDEN);
throw new ForbiddenException('Ecosystem role not match');
}

} else {
throw new HttpException('organization & ecosystem is required', HttpStatus.BAD_REQUEST);
throw new BadRequestException('organization & ecosystem is required');
}

// Sending user friendly message if a user attempts to access an API that is inaccessible to their role
Expand Down
29 changes: 7 additions & 22 deletions apps/api-gateway/src/ecosystem/dtos/get-members.dto.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,20 @@
import { Transform, Type } from 'class-transformer';
import { Transform } from 'class-transformer';
import { trim } from '@credebl/common/cast.helper';

import { ApiProperty } from '@nestjs/swagger';
import { IsEnum, IsOptional } from 'class-validator';
import { SortFields } from 'apps/connection/src/enum/connection.enum';
import { SortValue } from '@credebl/enum/enum';

export class GetAllEcosystemMembersDto {

@ApiProperty({ required: false, example: '1' })
@IsOptional()
pageNumber: number;

@ApiProperty({ required: false, example: '10' })
@IsOptional()
pageSize: number;

@ApiProperty({ required: false })
@IsOptional()
@Transform(({ value }) => trim(value))
@Type(() => String)
search: string = '';
import { SortMembers, SortValue } from '@credebl/enum/enum';
import { PaginationDto } from '@credebl/common/dtos/pagination.dto';

export class GetAllEcosystemMembersDto extends PaginationDto {
@ApiProperty({
enum: [SortMembers.CREATED_DATE_TIME, SortMembers.ID, SortMembers.ORGANIZATION, SortMembers.STATUS],
required: false
})
@Transform(({ value }) => trim(value))
@IsOptional()
@IsEnum(SortFields)
sortField: string = SortFields.CREATED_DATE_TIME;
@IsEnum(SortMembers)
sortField: string = SortMembers.CREATED_DATE_TIME;

@ApiProperty({
enum: [SortValue.DESC, SortValue.ASC],
Expand All @@ -38,5 +24,4 @@ export class GetAllEcosystemMembersDto {
@IsOptional()
@IsEnum(SortValue)
sortBy: string = SortValue.DESC;

}
13 changes: 7 additions & 6 deletions apps/api-gateway/src/ecosystem/ecosystem.controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ApiBearerAuth, ApiExcludeEndpoint, ApiForbiddenResponse, ApiOperation, ApiQuery, ApiResponse, ApiTags, ApiUnauthorizedResponse } from '@nestjs/swagger';
import { EcosystemService } from './ecosystem.service';
import { Controller, UseFilters, Put, Post, Get, Body, Param, UseGuards, Query, BadRequestException, Delete, HttpStatus, Res } from '@nestjs/common';
import { Controller, UseFilters, Put, Post, Get, Body, Param, UseGuards, Query, BadRequestException, Delete, HttpStatus, Res, ParseUUIDPipe } from '@nestjs/common';
import { RequestCredDefDto, RequestSchemaDto } from './dtos/request-schema.dto';
import IResponse from '@credebl/common/interfaces/response.interface';
import { Response } from 'express';
Expand Down Expand Up @@ -256,7 +256,7 @@ export class EcosystemController {
@EcosystemsRoles(EcosystemRoles.ECOSYSTEM_OWNER, EcosystemRoles.ECOSYSTEM_LEAD, EcosystemRoles.ECOSYSTEM_MEMBER)
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), EcosystemRolesGuard, OrgRolesGuard)
@ApiResponse({ status: 200, description: 'Success', type: ApiResponseDto })
@ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto })
@ApiOperation({ summary: 'Get ecosystem members list', description: 'Get ecosystem members list.' })
@ApiQuery({
name: 'pageNumber',
Expand All @@ -274,18 +274,19 @@ export class EcosystemController {
required: false
})
async getEcosystemMembers(
@Param('ecosystemId') ecosystemId: string,
@Param('ecosystemId', new ParseUUIDPipe({exceptionFactory: (): Error => { throw new BadRequestException(`Invalid format for ecosystemId`); }})) ecosystemId: string,
@Param('orgId') orgId: string,
@Query() getEcosystemMembers: GetAllEcosystemMembersDto,
@Res() res: Response): Promise<Response> {

const members = await this.ecosystemService.getEcosystemMembers(ecosystemId, getEcosystemMembers);
const finalResponse: IResponse = {
statusCode: 200,
statusCode: HttpStatus.OK,
message: ResponseMessages.ecosystem.success.fetchMembers,
data: members?.response
data: members
};

return res.status(200).json(finalResponse);
return res.status(HttpStatus.OK).json(finalResponse);
}

@Post('/:ecosystemId/:orgId/transaction/schema')
Expand Down
9 changes: 4 additions & 5 deletions apps/api-gateway/src/ecosystem/ecosystem.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,10 @@ export class EcosystemService extends BaseService {
*/
async getEcosystemMembers(
ecosystemId: string,
getEcosystemMembers: GetAllEcosystemMembersDto
payload: GetAllEcosystemMembersDto
): Promise<{ response: object }> {
const { pageNumber, pageSize, search, sortBy } = getEcosystemMembers;
const payload = { ecosystemId, pageNumber, pageSize, search, sortBy };
return this.sendNats(this.serviceProxy, 'fetch-ecosystem-members', payload);
payload['ecosystemId'] = ecosystemId;
return this.sendNatsMessage(this.serviceProxy, 'fetch-ecosystem-members', payload);
}

/**
Expand Down Expand Up @@ -128,7 +127,7 @@ export class EcosystemService extends BaseService {

async fetchEcosystemOrg(ecosystemId: string, orgId: string): Promise<{ response: object }> {
const payload = { ecosystemId, orgId };
return this.sendNats(this.serviceProxy, 'fetch-ecosystem-org-data', payload);
return this.sendNatsMessage(this.serviceProxy, 'fetch-ecosystem-org-data', payload);
}

async getEndorsementTranasactions(
Expand Down
1 change: 1 addition & 0 deletions apps/ecosystem/interfaces/ecosystemMembers.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export interface EcosystemMembersPayload {
pageSize: number;
search: string;
sortBy: string;
sortField: string;
}
2 changes: 1 addition & 1 deletion apps/ecosystem/src/ecosystem.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export class EcosystemController {
*/
@MessagePattern({ cmd: 'fetch-ecosystem-members' })
async getEcosystemMembers(@Body() payload: EcosystemMembersPayload): Promise<object> {
return this.ecosystemService.getEcoystemMembers(payload);
return this.ecosystemService.getEcosystemMembers(payload);
}

/**
Expand Down
134 changes: 70 additions & 64 deletions apps/ecosystem/src/ecosystem.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ResponseMessages } from '@credebl/common/response-messages';
import { NotFoundException } from '@nestjs/common';
import { CommonConstants } from '@credebl/common/common.constant';
import { GetAllSchemaList } from '../interfaces/endorsements.interface';
import { SortValue } from '@credebl/enum/enum';
// eslint-disable-next-line camelcase

@Injectable()
Expand Down Expand Up @@ -160,7 +161,7 @@ export class EcosystemRepository {
}
})
]);

return {
ecosystemDetails,
totalCount: ecosystemCount
Expand All @@ -170,7 +171,7 @@ export class EcosystemRepository {
throw error;
}
}


/**
*
Expand Down Expand Up @@ -486,62 +487,67 @@ export class EcosystemRepository {
* @returns users list
*/

async findEcosystemMembers(
ecosystemId: string,
pageNumber: number,
pageSize: number,
search: string,
sortBy: string
): Promise<object> {
try {
const result = await this.prisma.$transaction([
this.prisma.ecosystem_orgs.findMany({
where: {
ecosystemId,
OR: [
{
organisation: {
name: { contains: search, mode: 'insensitive' },
// eslint-disable-next-line camelcase
org_agents: {
some: {
orgDid: { contains: search, mode: 'insensitive' }
async findEcosystemMembers(
ecosystemId: string,
pageNumber: number,
pageSize: number,
search: string,
sortBy: string,
sortField: string
): Promise<object> {
try {
const result = await this.prisma.$transaction([
this.prisma.ecosystem_orgs.findMany({
where: {
ecosystemId,
OR: [
{
organisation: {
name: { contains: search, mode: 'insensitive' }
}
},
{
organisation: {
// eslint-disable-next-line camelcase
org_agents: {
some: {
orgDid: { contains: search, mode: 'insensitive' }
}
}
}
}
]
},
include: {
ecosystem: true,
ecosystemRole: true,
organisation: {
select: {
name: true,
orgSlug: true,
// eslint-disable-next-line camelcase
org_agents: true
}
}
]
},
include: {
ecosystem: true,
ecosystemRole: true,
organisation: {
select: {
name: true,
orgSlug: true,
// eslint-disable-next-line camelcase
org_agents: true
}
},
take: Number(pageSize),
skip: (pageNumber - 1) * pageSize,
orderBy: {
[sortField]: SortValue.ASC === sortBy ? 'asc' : 'desc'
}
},
take: Number(pageSize),
skip: (pageNumber - 1) * pageSize,
orderBy: {
createDateTime: 'asc' === sortBy ? 'asc' : 'desc'
}
}),
this.prisma.ecosystem_orgs.count({
where: {
ecosystemId
}
})
]);
return result;
} catch (error) {
this.logger.error(`error: ${JSON.stringify(error)}`);
throw error;
}),
this.prisma.ecosystem_orgs.count({
where: {
ecosystemId
}
})
]);
return result;
} catch (error) {
this.logger.error(`error: ${JSON.stringify(error)}`);
throw error;
}
}
}

async getEcosystemInvitationsPagination(queryObject: object, pageNumber: number, pageSize: number): Promise<IEcosystemInvitation> {
try {
Expand Down Expand Up @@ -590,18 +596,18 @@ async findEcosystemMembers(
async fetchEcosystemOrg(
payload: object
): Promise<object> {

return this.prisma.ecosystem_orgs.findFirst({
where: {
...payload
},
select: {
ecosystem: true,
ecosystemRole: true,
organisation: true
}
});

where: {
...payload
},
select: {
ecosystem: true,
ecosystemRole: true,
organisation: true
}
});
}


Expand Down Expand Up @@ -833,7 +839,7 @@ async findEcosystemMembers(
schemaTransactionResponse: SchemaTransactionResponse,
requestBody: object,
type: endorsementTransactionType
// eslint-disable-next-line camelcase
// eslint-disable-next-line camelcase
): Promise<endorsement_transaction> {
try {
const { endorserDid, authorDid, requestPayload, status, ecosystemOrgId, userId } = schemaTransactionResponse;
Expand Down
7 changes: 4 additions & 3 deletions apps/ecosystem/src/ecosystem.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1109,15 +1109,16 @@ export class EcosystemService {
* @returns Ecosystem members list
*/

async getEcoystemMembers(payload: EcosystemMembersPayload): Promise<object> {
async getEcosystemMembers(payload: EcosystemMembersPayload): Promise<object> {
try {
const { ecosystemId, pageNumber, pageSize, search, sortBy } = payload;
const { ecosystemId, pageNumber, pageSize, search, sortBy, sortField } = payload;
const getEcosystemMember = await this.ecosystemRepository.findEcosystemMembers(
ecosystemId,
pageNumber,
pageSize,
search,
sortBy
sortBy,
sortField
);

const ecosystemMemberResponse = {
Expand Down
7 changes: 7 additions & 0 deletions libs/enum/src/enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ export enum AutoAccept {
Never = "never"
}

export enum SortMembers {
CREATED_DATE_TIME = 'createDateTime',
STATUS = 'status',
ID = 'id',
ORGANIZATION = 'organization'
}

const transitionMap: { [key in Invitation]: Invitation[] } = {
[Invitation.PENDING]: [Invitation.ACCEPTED, Invitation.REJECTED],
[Invitation.ACCEPTED]: [],
Expand Down
4 changes: 4 additions & 0 deletions libs/http-exception.filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ export class HttpExceptionFilter implements ExceptionFilter {
httpStatus = HttpStatus.BAD_REQUEST;
message = exception?.response?.message || exception?.message;
break;
case 'P2023': // Inconsistent column data: {message}
httpStatus = HttpStatus.BAD_REQUEST;
message = exception?.meta?.message || exception?.message;
break;
case 'P2018': // The required connected records were not found. {details}
case 'P2025': // An operation failed because it depends on one or more records that were required but not found. {cause}
case 'P2015': // A related record could not be found. {details}
Expand Down

0 comments on commit d791fbc

Please sign in to comment.