From ab68e52efe3902463be17560dffc85bc84e37624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20G=C3=BCnther?= Date: Wed, 12 Nov 2025 17:42:45 +0100 Subject: [PATCH] apply feedback --- apps/api/src/app/import/import.service.ts | 13 +++--- apps/api/src/app/order/order.service.ts | 17 +++---- .../src/events/asset-profile-changed.event.ts | 9 ++-- .../events/asset-profile-changed.listener.ts | 44 ++++++------------- apps/api/src/events/events.module.ts | 4 +- 5 files changed, 35 insertions(+), 52 deletions(-) diff --git a/apps/api/src/app/import/import.service.ts b/apps/api/src/app/import/import.service.ts index dc60abd76..fc97745bf 100644 --- a/apps/api/src/app/import/import.service.ts +++ b/apps/api/src/app/import/import.service.ts @@ -609,15 +609,16 @@ export class ImportService { priority: DATA_GATHERING_QUEUE_PRIORITY_HIGH }); - uniqueActivities.forEach(({ SymbolProfile }) => { + for (const { SymbolProfile } of uniqueActivities) { this.eventEmitter.emit( AssetProfileChangedEvent.getName(), - new AssetProfileChangedEvent( - SymbolProfile.currency, - SymbolProfile.symbol - ) + new AssetProfileChangedEvent({ + currency: SymbolProfile.currency, + dataSource: SymbolProfile.dataSource, + symbol: SymbolProfile.symbol + }) ); - }); + } } return activities; diff --git a/apps/api/src/app/order/order.service.ts b/apps/api/src/app/order/order.service.ts index b02d5dfb8..7dc6c646d 100644 --- a/apps/api/src/app/order/order.service.ts +++ b/apps/api/src/app/order/order.service.ts @@ -227,18 +227,19 @@ export class OrderService { } this.eventEmitter.emit( - PortfolioChangedEvent.getName(), - new PortfolioChangedEvent({ - userId: order.userId + AssetProfileChangedEvent.getName(), + new AssetProfileChangedEvent({ + currency: order.SymbolProfile.currency, + dataSource: order.SymbolProfile.dataSource, + symbol: order.SymbolProfile.symbol }) ); this.eventEmitter.emit( - AssetProfileChangedEvent.getName(), - new AssetProfileChangedEvent( - order.SymbolProfile.currency, - order.SymbolProfile.symbol - ) + PortfolioChangedEvent.getName(), + new PortfolioChangedEvent({ + userId: order.userId + }) ); return order; diff --git a/apps/api/src/events/asset-profile-changed.event.ts b/apps/api/src/events/asset-profile-changed.event.ts index edb0a5949..46a8c5db4 100644 --- a/apps/api/src/events/asset-profile-changed.event.ts +++ b/apps/api/src/events/asset-profile-changed.event.ts @@ -1,12 +1,11 @@ -export class AssetProfileChangedEvent { - private static readonly eventName = 'asset-profile.changed'; +import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; +export class AssetProfileChangedEvent { public constructor( - public readonly currency: string, - public readonly symbol: string + public readonly data: AssetProfileIdentifier & { currency: string } ) {} public static getName(): string { - return AssetProfileChangedEvent.eventName; + return 'assetProfile.changed'; } } diff --git a/apps/api/src/events/asset-profile-changed.listener.ts b/apps/api/src/events/asset-profile-changed.listener.ts index 11bd0be81..cc73d0cc4 100644 --- a/apps/api/src/events/asset-profile-changed.listener.ts +++ b/apps/api/src/events/asset-profile-changed.listener.ts @@ -1,7 +1,7 @@ +import { OrderService } from '@ghostfolio/api/app/order/order.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; -import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import { DataGatheringService } from '@ghostfolio/api/services/queues/data-gathering/data-gathering.service'; import { DEFAULT_CURRENCY } from '@ghostfolio/common/config'; @@ -17,7 +17,7 @@ export class AssetProfileChangedListener { private readonly dataGatheringService: DataGatheringService, private readonly dataProviderService: DataProviderService, private readonly exchangeRateDataService: ExchangeRateDataService, - private readonly prismaService: PrismaService + private readonly orderService: OrderService ) {} @OnEvent(AssetProfileChangedEvent.getName()) @@ -30,62 +30,44 @@ export class AssetProfileChangedListener { return; } - if (event.currency === DEFAULT_CURRENCY) { + if (event.data.currency === DEFAULT_CURRENCY) { return; } Logger.log( - `Asset profile changed: ${event.symbol} (${event.currency}). Checking if exchange rate gathering is needed.`, + `Asset profile changed: ${event.data.symbol} (${event.data.currency})`, 'AssetProfileChangedListener' ); const existingCurrencies = this.exchangeRateDataService.getCurrencies(); - const currencyAlreadyExists = existingCurrencies.includes(event.currency); + const currencyAlreadyExists = existingCurrencies.includes( + event.data.currency + ); if (currencyAlreadyExists) { return; } Logger.log( - `New currency detected: ${event.currency}. Initializing exchange rate data service.`, + `New currency detected: ${event.data.currency}`, 'AssetProfileChangedListener' ); await this.exchangeRateDataService.initialize(); - if ( - !this.exchangeRateDataService.hasCurrencyPair( - DEFAULT_CURRENCY, - event.currency - ) - ) { - Logger.warn( - `Currency pair ${DEFAULT_CURRENCY}${event.currency} was not added after initialization.`, - 'AssetProfileChangedListener' - ); - return; - } - - const firstOrderWithCurrency = await this.prismaService.order.findFirst({ - orderBy: [{ date: 'asc' }], - select: { date: true }, - where: { - SymbolProfile: { - currency: event.currency - } - } - }); + const { dateOfFirstActivity } = + await this.orderService.getStatisticsByCurrency(event.data.currency); - const startDate = firstOrderWithCurrency.date ?? new Date(); + const startDate = dateOfFirstActivity ?? new Date(); Logger.log( - `Triggering exchange rate data gathering for ${DEFAULT_CURRENCY}${event.currency} from ${startDate.toISOString()}.`, + `Triggering exchange rate data gathering for ${DEFAULT_CURRENCY}${event.data.currency} from ${startDate.toISOString()}.`, 'AssetProfileChangedListener' ); await this.dataGatheringService.gatherSymbol({ dataSource: this.dataProviderService.getDataSourceForExchangeRates(), - symbol: `${DEFAULT_CURRENCY}${event.currency}`, + symbol: `${DEFAULT_CURRENCY}${event.data.currency}`, date: startDate }); } diff --git a/apps/api/src/events/events.module.ts b/apps/api/src/events/events.module.ts index aa9ccd596..ece67ebe0 100644 --- a/apps/api/src/events/events.module.ts +++ b/apps/api/src/events/events.module.ts @@ -1,8 +1,8 @@ +import { OrderModule } from '@ghostfolio/api/app/order/order.module'; import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module'; import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module'; import { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module'; import { ExchangeRateDataModule } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.module'; -import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module'; import { DataGatheringModule } from '@ghostfolio/api/services/queues/data-gathering/data-gathering.module'; import { Module } from '@nestjs/common'; @@ -16,7 +16,7 @@ import { PortfolioChangedListener } from './portfolio-changed.listener'; DataGatheringModule, DataProviderModule, ExchangeRateDataModule, - PrismaModule, + OrderModule, RedisCacheModule ], providers: [AssetProfileChangedListener, PortfolioChangedListener]