Browse Source

feat(api): extend with performances data

pull/4634/head
KenTandrian 4 months ago
parent
commit
b36d57514c
  1. 4
      apps/api/src/app/endpoints/watchlist/watchlist.module.ts
  2. 40
      apps/api/src/app/endpoints/watchlist/watchlist.service.ts
  3. 9
      libs/common/src/lib/interfaces/responses/watchlist-response.interface.ts

4
apps/api/src/app/endpoints/watchlist/watchlist.module.ts

@ -1,6 +1,8 @@
import { TransformDataSourceInRequestModule } from '@ghostfolio/api/interceptors/transform-data-source-in-request/transform-data-source-in-request.module'; import { TransformDataSourceInRequestModule } from '@ghostfolio/api/interceptors/transform-data-source-in-request/transform-data-source-in-request.module';
import { TransformDataSourceInResponseModule } from '@ghostfolio/api/interceptors/transform-data-source-in-response/transform-data-source-in-response.module'; import { TransformDataSourceInResponseModule } from '@ghostfolio/api/interceptors/transform-data-source-in-response/transform-data-source-in-response.module';
import { BenchmarkModule } from '@ghostfolio/api/services/benchmark/benchmark.module';
import { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module'; import { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module';
import { MarketDataModule } from '@ghostfolio/api/services/market-data/market-data.module';
import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module'; import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module';
import { DataGatheringModule } from '@ghostfolio/api/services/queues/data-gathering/data-gathering.module'; import { DataGatheringModule } from '@ghostfolio/api/services/queues/data-gathering/data-gathering.module';
import { SymbolProfileModule } from '@ghostfolio/api/services/symbol-profile/symbol-profile.module'; import { SymbolProfileModule } from '@ghostfolio/api/services/symbol-profile/symbol-profile.module';
@ -13,8 +15,10 @@ import { WatchlistService } from './watchlist.service';
@Module({ @Module({
controllers: [WatchlistController], controllers: [WatchlistController],
imports: [ imports: [
BenchmarkModule,
DataGatheringModule, DataGatheringModule,
DataProviderModule, DataProviderModule,
MarketDataModule,
PrismaModule, PrismaModule,
SymbolProfileModule, SymbolProfileModule,
TransformDataSourceInRequestModule, TransformDataSourceInRequestModule,

40
apps/api/src/app/endpoints/watchlist/watchlist.service.ts

@ -1,17 +1,22 @@
import { BenchmarkService } from '@ghostfolio/api/services/benchmark/benchmark.service';
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { DataGatheringService } from '@ghostfolio/api/services/queues/data-gathering/data-gathering.service'; import { DataGatheringService } from '@ghostfolio/api/services/queues/data-gathering/data-gathering.service';
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service'; import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service';
import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; import { WatchlistResponse } from '@ghostfolio/common/interfaces';
import { BadRequestException, Injectable } from '@nestjs/common'; import { BadRequestException, Injectable } from '@nestjs/common';
import { DataSource, Prisma } from '@prisma/client'; import { DataSource, Prisma } from '@prisma/client';
import ms from 'ms';
@Injectable() @Injectable()
export class WatchlistService { export class WatchlistService {
public constructor( public constructor(
private readonly benchmarkService: BenchmarkService,
private readonly dataGatheringService: DataGatheringService, private readonly dataGatheringService: DataGatheringService,
private readonly dataProviderService: DataProviderService, private readonly dataProviderService: DataProviderService,
private readonly marketDataService: MarketDataService,
private readonly prismaService: PrismaService, private readonly prismaService: PrismaService,
private readonly symbolProfileService: SymbolProfileService private readonly symbolProfileService: SymbolProfileService
) {} ) {}
@ -87,7 +92,7 @@ export class WatchlistService {
public async getWatchlistItems( public async getWatchlistItems(
userId: string userId: string
): Promise<AssetProfileIdentifier[]> { ): Promise<WatchlistResponse['watchlist']> {
const user = await this.prismaService.user.findUnique({ const user = await this.prismaService.user.findUnique({
select: { select: {
watchlist: { watchlist: {
@ -97,6 +102,35 @@ export class WatchlistService {
where: { id: userId } where: { id: userId }
}); });
return user.watchlist ?? []; const quotes = await this.dataProviderService.getQuotes({
items: user.watchlist.map(({ dataSource, symbol }) => {
return { dataSource, symbol };
}),
requestTimeout: ms('30 seconds'),
useCache: false
});
const watchlist = await Promise.all(
user.watchlist.map(async ({ dataSource, symbol }) => {
const ath = await this.marketDataService.getMax({ dataSource, symbol });
const performancePercent =
this.benchmarkService.calculateChangeInPercentage(
ath.marketPrice,
quotes[symbol]?.marketPrice
);
return {
dataSource,
symbol,
performances: {
allTimeHigh: {
date: ath?.date,
performancePercent
}
}
};
})
);
return watchlist;
} }
} }

9
libs/common/src/lib/interfaces/responses/watchlist-response.interface.ts

@ -1,5 +1,10 @@
import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; import {
AssetProfileIdentifier,
Benchmark
} from '@ghostfolio/common/interfaces';
export interface WatchlistResponse { export interface WatchlistResponse {
watchlist: AssetProfileIdentifier[]; watchlist: (AssetProfileIdentifier & {
performances: Benchmark['performances'];
})[];
} }

Loading…
Cancel
Save