From b5777d3e70229109007b845fde3cd75973b5f651 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 23 Jul 2026 19:18:33 +0200 Subject: [PATCH] Recompute portfolio snapshot on portfolio change --- .../calculator/portfolio-calculator.ts | 17 ++++++++++------- .../src/events/portfolio-changed.listener.ts | 18 +++++++++++++----- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index c1e795c4af..606c223b48 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -1097,15 +1097,18 @@ export abstract class PortfolioCalculator { let cachedPortfolioSnapshot: PortfolioSnapshot; let isCachedPortfolioSnapshotExpired = false; - const jobId = this.userId; + const portfolioSnapshotKey = this.redisCacheService.getPortfolioSnapshotKey( + { + filters: this.filters, + userId: this.userId + } + ); + + const jobId = portfolioSnapshotKey; try { - const cachedPortfolioSnapshotValue = await this.redisCacheService.get( - this.redisCacheService.getPortfolioSnapshotKey({ - filters: this.filters, - userId: this.userId - }) - ); + const cachedPortfolioSnapshotValue = + await this.redisCacheService.get(portfolioSnapshotKey); const { expiration, portfolioSnapshot }: PortfolioSnapshotValue = JSON.parse(cachedPortfolioSnapshotValue); diff --git a/apps/api/src/events/portfolio-changed.listener.ts b/apps/api/src/events/portfolio-changed.listener.ts index 36a9e704a4..f376cde044 100644 --- a/apps/api/src/events/portfolio-changed.listener.ts +++ b/apps/api/src/events/portfolio-changed.listener.ts @@ -58,25 +58,33 @@ export class PortfolioChangedListener { const user = await this.userService.user({ id: userId }); const userSettings = user.settings.settings; + const filters = this.apiService.buildFiltersFromUserSettings({ + userSettings + }); + // Recompute in the background to avoid a cold start on the next request await this.portfolioSnapshotService.addJobToQueue({ data: { + filters, userId, calculationType: userSettings.performanceCalculationType, - filters: this.apiService.buildFiltersFromUserSettings({ - userSettings - }), userCurrency: userSettings.baseCurrency }, name: PORTFOLIO_SNAPSHOT_PROCESS_JOB_NAME, opts: { ...PORTFOLIO_SNAPSHOT_PROCESS_JOB_OPTIONS, - jobId: userId, + jobId: this.redisCacheService.getPortfolioSnapshotKey({ + filters, + userId + }), priority: PORTFOLIO_SNAPSHOT_COMPUTATION_QUEUE_PRIORITY_LOW } }); } catch (error) { - this.logger.error(error); + this.logger.error( + `Portfolio snapshot of user '${userId}' could not be recomputed`, + error + ); } } }