From f352fe7dd89775dfae8be3bf299b35da6ec46fa8 Mon Sep 17 00:00:00 2001 From: pallavighule Date: Tue, 4 Mar 2025 22:25:32 +0530 Subject: [PATCH] added API for fetch schemas by schema ids Signed-off-by: pallavighule --- .../api-gateway/src/dtos/create-schema.dto.ts | 7 ++++- .../src/schema/dtos/get-schema-by-ids-dto.ts | 14 ++++++++++ .../src/schema/schema.controller.ts | 28 +++++++++++++++++++ apps/api-gateway/src/schema/schema.service.ts | 6 ++++ .../interfaces/schema-payload.interface.ts | 10 ++++++- .../src/schema/interfaces/schema.interface.ts | 1 + .../schema/repositories/schema.repository.ts | 26 ++++++++++++++++- apps/ledger/src/schema/schema.controller.ts | 9 +++++- apps/ledger/src/schema/schema.service.ts | 26 ++++++++++++----- .../migration.sql | 2 ++ libs/prisma-service/prisma/schema.prisma | 1 + 11 files changed, 119 insertions(+), 11 deletions(-) create mode 100644 apps/api-gateway/src/schema/dtos/get-schema-by-ids-dto.ts create mode 100644 libs/prisma-service/prisma/migrations/20250304144138_added_is_sample_in_schema_table/migration.sql diff --git a/apps/api-gateway/src/dtos/create-schema.dto.ts b/apps/api-gateway/src/dtos/create-schema.dto.ts index 61f45e2b3..2cdecd7f2 100644 --- a/apps/api-gateway/src/dtos/create-schema.dto.ts +++ b/apps/api-gateway/src/dtos/create-schema.dto.ts @@ -158,7 +158,12 @@ export class GenericSchemaDTO { @IsEnum(SchemaTypeEnum, { message: 'Type must be a valid schema type' }) @IsNotEmpty({ message: 'Type is required' }) type: SchemaTypeEnum; - + + @ApiPropertyOptional({ default: false }) + @IsBoolean() + @IsOptional() + @IsNotEmpty({ message: 'isSample property is required' }) + isSample: boolean = false; @ApiProperty({ type: Object, oneOf: [ diff --git a/apps/api-gateway/src/schema/dtos/get-schema-by-ids-dto.ts b/apps/api-gateway/src/schema/dtos/get-schema-by-ids-dto.ts new file mode 100644 index 000000000..3caff9445 --- /dev/null +++ b/apps/api-gateway/src/schema/dtos/get-schema-by-ids-dto.ts @@ -0,0 +1,14 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { IsArray, IsNotEmpty, IsString } from 'class-validator'; + +export class SchemaIdsDto { + @ApiProperty({ + description: 'Array of schema IDs', + type: [String], + example: ['schema1', 'schema2'] + }) + @IsArray() + @IsNotEmpty({ message: 'Schema IDs array cannot be empty' }) + @IsString({ each: true }) + schemaIds: string[]; +} \ No newline at end of file diff --git a/apps/api-gateway/src/schema/schema.controller.ts b/apps/api-gateway/src/schema/schema.controller.ts index b1c172a1d..e07f0ad6e 100644 --- a/apps/api-gateway/src/schema/schema.controller.ts +++ b/apps/api-gateway/src/schema/schema.controller.ts @@ -21,6 +21,7 @@ import { GenericSchemaDTO } from '../dtos/create-schema.dto'; import { CustomExceptionFilter } from 'apps/api-gateway/common/exception-handler'; import { CredDefSortFields, SortFields } from '@credebl/enum/enum'; import { TrimStringParamPipe } from '@credebl/common/cast.helper'; +import { SchemaIdsDto } from './dtos/get-schema-by-ids-dto'; @UseFilters(CustomExceptionFilter) @Controller('orgs') @@ -161,6 +162,32 @@ export class SchemaController { } + /** + * Retrieves a list of schemas associated with a given Ids. + * @returns A list of schemas associated with a given Ids. + */ + @Get('/schemas-by-ids') + @ApiOperation({ + summary: 'Retrieves a list of schemas associated with a given Ids', + description: 'Retrieves a list of schemas associated with a given Ids' + }) + @ApiResponse({ status: HttpStatus.OK, description: 'Success', type: ApiResponseDto }) + async getSchemasByIds( + @Body() schemaDetails: SchemaIdsDto, + @Res() res: Response + + ): Promise { + const schemasResponse = await this.appService.getSchemasByIds(schemaDetails); + + const finalResponse: IResponse = { + statusCode: HttpStatus.OK, + message: ResponseMessages.schema.success.fetch, + data: schemasResponse + }; + return res.status(HttpStatus.OK).json(finalResponse); + } + + /** * Create and register various types of schemas. * @@ -186,4 +213,5 @@ export class SchemaController { }; return res.status(HttpStatus.CREATED).json(finalResponse); } + } diff --git a/apps/api-gateway/src/schema/schema.service.ts b/apps/api-gateway/src/schema/schema.service.ts index 2360dea2e..43467ab25 100644 --- a/apps/api-gateway/src/schema/schema.service.ts +++ b/apps/api-gateway/src/schema/schema.service.ts @@ -7,6 +7,8 @@ import { ISchemaInfo, IUserRequestInterface } from './interfaces'; import { ICredDefWithPagination, ISchemaData, ISchemasWithPagination } from '@credebl/common/interfaces/schema.interface'; import { GetCredentialDefinitionBySchemaIdDto } from './dtos/get-all-schema.dto'; import { NATSClient } from '@credebl/common/NATSClient'; +import { SchemaIdsDto } from './dtos/get-schema-by-ids-dto'; +import { SchemaDetails } from 'apps/issuance/interfaces/issuance.interfaces'; @Injectable() export class SchemaService extends BaseService { @@ -32,6 +34,10 @@ export class SchemaService extends BaseService { return this.natsClient.sendNatsMessage(this.schemaServiceProxy, 'get-schemas', schemaSearch); } + getSchemasByIds(schemaDetails: SchemaIdsDto): Promise { + return this.natsClient.sendNatsMessage(this.schemaServiceProxy, 'get-schemas-by-ids', schemaDetails); + } + getcredDefListBySchemaId(schemaSearchCriteria: GetCredentialDefinitionBySchemaIdDto, user: IUserRequestInterface): Promise { const payload = { schemaSearchCriteria, user }; return this.natsClient.sendNatsMessage(this.schemaServiceProxy, 'get-cred-def-list-by-schemas-id', payload); diff --git a/apps/ledger/src/schema/interfaces/schema-payload.interface.ts b/apps/ledger/src/schema/interfaces/schema-payload.interface.ts index c988c20c3..644e29f91 100644 --- a/apps/ledger/src/schema/interfaces/schema-payload.interface.ts +++ b/apps/ledger/src/schema/interfaces/schema-payload.interface.ts @@ -121,4 +121,12 @@ export interface ISaveSchema { export interface SaveSchemaPayload { schemaDetails: ISaveSchema -} \ No newline at end of file +} + + +export interface SchemaDetails { + id: string; + type: string; + isSchemaArchived: boolean; + isSample: boolean; + } \ No newline at end of file diff --git a/apps/ledger/src/schema/interfaces/schema.interface.ts b/apps/ledger/src/schema/interfaces/schema.interface.ts index 36bbb5d9f..43d6c2fde 100644 --- a/apps/ledger/src/schema/interfaces/schema.interface.ts +++ b/apps/ledger/src/schema/interfaces/schema.interface.ts @@ -95,6 +95,7 @@ export interface ICreateW3CSchema { } export interface IGenericSchema { type: SchemaTypeEnum; + isSample:boolean, schemaPayload: ICreateSchema | ICreateW3CSchema; } diff --git a/apps/ledger/src/schema/repositories/schema.repository.ts b/apps/ledger/src/schema/repositories/schema.repository.ts index 78b1f97e0..180e09ff0 100644 --- a/apps/ledger/src/schema/repositories/schema.repository.ts +++ b/apps/ledger/src/schema/repositories/schema.repository.ts @@ -2,7 +2,7 @@ import { ConflictException, Injectable, InternalServerErrorException, Logger } from '@nestjs/common'; import { PrismaService } from '@credebl/prisma-service'; import { ledgers, org_agents, org_agents_type, organisation, Prisma, schema } from '@prisma/client'; -import { ISchema, ISchemaExist, ISchemaSearchCriteria, ISaveSchema } from '../interfaces/schema-payload.interface'; +import { ISchema, ISchemaExist, ISchemaSearchCriteria, ISaveSchema, SchemaDetails } from '../interfaces/schema-payload.interface'; import { ResponseMessages } from '@credebl/common/response-messages'; import { AgentDetails, ISchemasWithCount } from '../interfaces/schema.interface'; import { SchemaType, SortValue } from '@credebl/enum/enum'; @@ -456,4 +456,28 @@ export class SchemaRepository { throw error; } } + + + async getSchemasByIds(schemaDetails:string[]): Promise { + try { + return await this.prisma.schema.findMany({ + where: { + schemaLedgerId: { + in: schemaDetails + } + }, + select: { + id: true, + type: true, + isSchemaArchived: true, + isSample: true + } + }); + + } catch (error) { + this.logger.error(`Error in retrieving schemas by schema ids: ${error}`); + throw new RpcException(error.response ? error.response : error); + } + } + } \ No newline at end of file diff --git a/apps/ledger/src/schema/schema.controller.ts b/apps/ledger/src/schema/schema.controller.ts index a423b8d22..98f5e9795 100644 --- a/apps/ledger/src/schema/schema.controller.ts +++ b/apps/ledger/src/schema/schema.controller.ts @@ -6,7 +6,8 @@ import { ISchemaCredDeffSearchInterface, ISchemaExist, ISchemaSearchPayload, - SaveSchemaPayload + SaveSchemaPayload, + SchemaDetails } from './interfaces/schema-payload.interface'; import { Prisma, schema } from '@prisma/client'; import { @@ -17,6 +18,7 @@ import { } from '@credebl/common/interfaces/schema.interface'; import { IschemaPayload } from './interfaces/schema.interface'; import { ISchemaId } from './schema.interface'; +import { SchemaIdsDto } from 'apps/api-gateway/src/schema/dtos/get-schema-by-ids-dto'; @Controller('schema') export class SchemaController { @@ -52,6 +54,11 @@ export class SchemaController { return this.schemaService.getSchemas(schemaSearchCriteria, orgId); } + @MessagePattern({ cmd: 'get-schemas-by-ids' }) + async getSchemasByIds(schemaDetails: SchemaIdsDto): Promise { + return this.schemaService.getSchemasByIds(schemaDetails.schemaIds); + } + @MessagePattern({ cmd: 'get-cred-def-list-by-schemas-id' }) async getcredDefListBySchemaId(payload: ISchemaCredDeffSearchInterface): Promise { return this.schemaService.getcredDefListBySchemaId(payload); diff --git a/apps/ledger/src/schema/schema.service.ts b/apps/ledger/src/schema/schema.service.ts index e747db035..114f51ea7 100644 --- a/apps/ledger/src/schema/schema.service.ts +++ b/apps/ledger/src/schema/schema.service.ts @@ -10,7 +10,7 @@ import { ClientProxy, RpcException } from '@nestjs/microservices'; import { BaseService } from 'libs/service/base.service'; import { SchemaRepository } from './repositories/schema.repository'; import { Prisma, schema } from '@prisma/client'; -import { ISaveSchema, ISchema, ISchemaCredDeffSearchInterface, ISchemaExist, ISchemaSearchCriteria, W3CCreateSchema } from './interfaces/schema-payload.interface'; +import { ISaveSchema, ISchema, ISchemaCredDeffSearchInterface, ISchemaExist, ISchemaSearchCriteria, SchemaDetails, W3CCreateSchema } from './interfaces/schema-payload.interface'; import { ResponseMessages } from '@credebl/common/response-messages'; import { ICreateSchema, ICreateW3CSchema, IGenericSchema, IUserRequestInterface } from './interfaces/schema.interface'; import { CreateSchemaAgentRedirection, GetSchemaAgentRedirection, ISchemaId } from './schema.interface'; @@ -48,7 +48,7 @@ export class SchemaService extends BaseService { const userId = user.id; try { - const {schemaPayload, type} = schemaDetails; + const {schemaPayload, type, isSample } = schemaDetails; if (type === SchemaTypeEnum.INDY) { @@ -247,7 +247,7 @@ export class SchemaService extends BaseService { } } else if (type === SchemaTypeEnum.JSON) { const josnSchemaDetails = schemaPayload as unknown as ICreateW3CSchema; - const createW3CSchema = await this.createW3CSchema(orgId, josnSchemaDetails, user.id); + const createW3CSchema = await this.createW3CSchema(orgId, josnSchemaDetails, user.id, isSample); return createW3CSchema; } } catch (error) { @@ -259,7 +259,7 @@ export class SchemaService extends BaseService { } } - async createW3CSchema(orgId:string, schemaPayload: ICreateW3CSchema, user: string): Promise { + async createW3CSchema(orgId:string, schemaPayload: ICreateW3CSchema, user: string, isSample:boolean): Promise { try { let createSchema; @@ -325,7 +325,7 @@ export class SchemaService extends BaseService { createSchema.schemaUrl = `${process.env.SCHEMA_FILE_SERVER_URL}${createSchemaPayload.data.schemaId}`; } - const storeW3CSchema = await this.storeW3CSchemas(createSchema, user, orgId, attributes); + const storeW3CSchema = await this.storeW3CSchemas(createSchema, user, orgId, attributes, isSample); if (!storeW3CSchema) { throw new BadRequestException(ResponseMessages.schema.error.storeW3CSchema, { @@ -524,7 +524,7 @@ export class SchemaService extends BaseService { return W3CSchema; } - private async storeW3CSchemas(schemaDetails, user, orgId, attributes): Promise { + private async storeW3CSchemas(schemaDetails, user, orgId, attributes, isSample): Promise { let ledgerDetails; const schemaServerUrl = `${process.env.SCHEMA_FILE_SERVER_URL}${schemaDetails.schemaId}`; const schemaRequest = await this.commonService @@ -563,7 +563,8 @@ export class SchemaService extends BaseService { publisherDid: schemaDetails.did, orgId, ledgerId: ledgerDetails.id, - type: SchemaType.W3C_Schema + type: SchemaType.W3C_Schema, + isSample }; const saveResponse = await this.schemaRepository.saveSchema( storeSchemaDetails @@ -928,4 +929,15 @@ export class SchemaService extends BaseService { throw new RpcException(error.response ? error.response : error); } } + + + async getSchemasByIds(schemaDetails: string[]): Promise { + try { + const schemaSearchResult = await this.schemaRepository.getSchemasByIds(schemaDetails); + return schemaSearchResult; + } catch (error) { + this.logger.error(`Error in getSchemasByIds: ${error}`); + throw new RpcException(error.response ? error.response : error); + } + } } \ No newline at end of file diff --git a/libs/prisma-service/prisma/migrations/20250304144138_added_is_sample_in_schema_table/migration.sql b/libs/prisma-service/prisma/migrations/20250304144138_added_is_sample_in_schema_table/migration.sql new file mode 100644 index 000000000..2c773a0b9 --- /dev/null +++ b/libs/prisma-service/prisma/migrations/20250304144138_added_is_sample_in_schema_table/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "schema" ADD COLUMN "isSample" BOOLEAN DEFAULT false; diff --git a/libs/prisma-service/prisma/schema.prisma b/libs/prisma-service/prisma/schema.prisma index ddde8f19d..dbed610b7 100644 --- a/libs/prisma-service/prisma/schema.prisma +++ b/libs/prisma-service/prisma/schema.prisma @@ -269,6 +269,7 @@ model schema { type String? @db.VarChar isSchemaArchived Boolean @default(false) credential_definition credential_definition[] + isSample Boolean? @default(false) } model credential_definition {