diff --git a/packages/apollo-collaboration-server/src/entity/gff3Object.dto.ts b/packages/apollo-collaboration-server/src/entity/gff3Object.dto.ts index f4502e253..dac43ccfb 100644 --- a/packages/apollo-collaboration-server/src/entity/gff3Object.dto.ts +++ b/packages/apollo-collaboration-server/src/entity/gff3Object.dto.ts @@ -28,3 +28,8 @@ export interface FeatureRangeSearchDto { start: number end: number } + +export interface FeatureIdsSearchDto { + featureIds: string[] + topLevel?: boolean +} diff --git a/packages/apollo-collaboration-server/src/features/features.controller.ts b/packages/apollo-collaboration-server/src/features/features.controller.ts index df5fd97e8..22006282f 100644 --- a/packages/apollo-collaboration-server/src/features/features.controller.ts +++ b/packages/apollo-collaboration-server/src/features/features.controller.ts @@ -1,13 +1,18 @@ import { + Body, Controller, Get, Logger, Param, ParseBoolPipe, + Post, Query, } from '@nestjs/common' -import { FeatureRangeSearchDto } from '../entity/gff3Object.dto' +import { + FeatureIdsSearchDto, + FeatureRangeSearchDto, +} from '../entity/gff3Object.dto' import { Role } from '../utils/role/role.enum' import { Validations } from '../utils/validation/validatation.decorator' @@ -37,14 +42,23 @@ export class FeaturesController { * or if search data was not found or in case of error throw exception */ @Get('getFeatures') - getFeatures(@Query() request: FeatureRangeSearchDto) { + getFeaturesByRange(@Query() request: FeatureRangeSearchDto) { this.logger.debug( - `getFeaturesByCriteria -method: refSeq: ${request.refSeq}, start: ${request.start}, end: ${request.end}`, + `getFeatures endpoint: refSeq: ${request.refSeq}, start: ${request.start}, end: ${request.end}`, ) return this.featuresService.findByRange(request) } + @Post('getByIds') + findByFeatureIds(@Body() request: FeatureIdsSearchDto) { + this.logger.debug(`: featureIds: ${JSON.stringify(request.featureIds)}`) + return this.featuresService.findByFeatureIds( + request.featureIds, + request.topLevel, + ) + } + @Get('count') async getFeatureCount(@Query() featureCountRequest: FeatureCountRequest) { this.logger.debug( diff --git a/packages/apollo-collaboration-server/src/features/features.service.ts b/packages/apollo-collaboration-server/src/features/features.service.ts index 21cc0054d..87f078048 100644 --- a/packages/apollo-collaboration-server/src/features/features.service.ts +++ b/packages/apollo-collaboration-server/src/features/features.service.ts @@ -117,6 +117,33 @@ export class FeaturesService { return } + async findByFeatureIds(featureIds: string[], topLevel?: boolean) { + const foundFeatures: Feature[] = [] + // all featureIds that have already been fetched + const fetchedFeatureIds = new Set() + + for (const featureId of featureIds) { + if (fetchedFeatureIds.has(featureId)) { + this.logger.debug(`FeatureId ${featureId} already fetched, skipping...`) + continue + } + + try { + const feature = await this.findById(featureId, topLevel) + foundFeatures.push(feature) + for (const id of feature.allIds) { + fetchedFeatureIds.add(id) + } + } catch (error) { + this.logger.error( + `Error occurred while fetching feature ${featureId}`, + error instanceof Error ? error.stack : String(error), + ) + } + } + return foundFeatures + } + /** * Get feature by featureId. When retrieving features by id, the features and any of its children are returned, but not any of its parent or sibling features. * @param featureId - featureId